Codeforces 963A Alternating Sum(等比数列求和+逆元+快速幂)


题目链接:http://codeforces.com/problemset/problem/963/A

题目大意:就是给了你n,a,b和一段长度为k的只有'+'和‘-’字符串,保证n+1被k整除,让你你计算。

解题思路:

暴力肯定超时的,我们可以先计算出0~k-1这一段的值,当做a1,可以发现如果把每段长度为k的段的值当做一个元素,他们之间是成等比的,比值q=(b/a)^k,

然后就直接用等比数列求和公式求出答案即可。昨天把q当成b/a了,我的脑子啊。。。

注意,判断q==1时不能通过判断a==b,而是判断(a/b)^k==1来实现。

代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<string>
13 #define lc(a) (a<<1)
14 #define rc(a) (a<<1|1)
15 #define MID(a,b) ((a+b)>>1)
16 #define fin(name)  freopen(name,"r",stdin)
17 #define fout(name) freopen(name,"w",stdout)
18 #define clr(arr,val) memset(arr,val,sizeof(arr))
19 #define _for(i,start,end) for(int i=start;i<=end;i++)
20 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
21 using namespace std;
22 typedef long long LL;
23 const LL MOD=1e9+9;
24 const double eps=1e-10;
25 
26 string str;
27 
28 LL fpow(LL x,LL n){
29     LL res=1;
30     while(n>0){
31         if(n&1) res=res*x%MOD;  //如果二进制最低位为1,则乘上x^(2^i)
32         x=x*x%MOD;                //将x平方并取模
33         n>>=1;
34     }
35     return (res%MOD+MOD)%MOD;
36 }
37 
38 LL extend_gcd(LL a,LL b,LL &x,LL &y){
39     if(!b){
40         x=1;
41         y=0;
42         return a;
43     }
44     LL gcd=extend_gcd(b,a%b,x,y);
45     LL t=x;
46     x=y;
47     y=t-(a/b)*x;
48     return gcd;
49 }
50 
51 LL NY(LL num){
52     LL x,y;
53     extend_gcd(num,MOD,x,y);
54     return (x%MOD+MOD)%MOD;
55 }
56 
57 int main(){
58     FAST_IO;
59     LL n,a,b,k;
60     cin>>n>>a>>b>>k;
61     cin>>str;
62     LL len=(n+1)/k;
63     LL sum=0;
64     for(int i=0;i<k;i++){
65         if(str[i]=='+')
66             sum=((sum+fpow(a,n-i)*fpow(b,i))%MOD+MOD)%MOD;
67         else
68             sum=((sum-fpow(a,n-i)*fpow(b,i))%MOD+MOD)%MOD;
69     }
70     LL ans;
71     //注意,比值q是(b/a)^k而不是(b/a)
72     LL q=fpow(NY(a),k)*fpow(b,k)%MOD;
73     if(q!=1){
74         LL _q=NY(q-1);
75         ans=(sum*(fpow(q,len)-1)%MOD*_q%MOD+MOD)%MOD;
76     }
77     else
78         ans=sum*len%MOD;
79     cout<<ans<<endl;
80     return 0;
81 }

优质内容筛选与推荐>>
1、添加应用栏
2、学生表 课程表 成绩表 教师表 50个常用sql语句
3、Python--网络编程-----解决粘包问题-简单版
4、Unity3D脚本中文系列教程(十)
5、PHP介绍


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号