[codeforces round#475 div2 ][C Alternating Sum ]

http://codeforces.com/contest/964/problem/C

题目大意:给出一个等比序列求和并且mod 1e9+9.

题目分析:等比数列的前n项和公式通过等公比错位相减法可以得到是Sn=A1*(q^n-1)/(q-1).这里注意q不能等于1.

坑点:而本题的q=(b/a)^k,由于a,b,k的数据范围也很大,所以需要求逆元来进行除法取模,而这个过程会出现b/a原本不等于1,而在求逆元取模之后的结果为1,所以不光要判断一下b/a的结果是否等于1,还要判断一下b*mypow(a,mod-2)%mod的结果是否等于1. 被这个坑卡了一个小时..orz

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 using namespace std;
 6 typedef long long ll;
 7 char ch[100005];
 8 const ll mod=1e9+9;
 9 ll mypow(ll x,ll y){
10     ll ans=1;
11     while(y){
12         if(y&1)ans=(ans%mod)*(x%mod)%mod;
13         x=(x%mod)*(x%mod)%mod;
14         y/=2;
15     }
16     return ans%mod;
17 }
18 int main(){
19     ll n,a,b,k;
20     cin>>n>>a>>b>>k;
21     scanf("%s",ch);
22         ll sum=0;
23         ll bb=1;
24         ll p=(mypow(a,n))%mod;
25     for(int i=0;i<k;i++)
26     {
27         if(ch[i]=='+')
28         {
29             sum=(sum+p)%mod;
30         }
31         else
32         sum=(sum-p+mod)%mod;
33         p=(p*b)%mod;
34         p=(p*mypow(a,mod-2))%mod;
35     }
36       ll ans=sum;
37     if(a==b){
38         sum=(sum%mod)*(((n+1)/k)%mod)%mod;
39     }
40     else{
41         ll ad1=mypow(b,k)%mod;
42         ll ad2=mypow(a,k)%mod;
43         ll ss=mypow(ad2,mod-2)%mod;
44         ss=(ss*ad1)%mod;
45         if(ss==1){
46             ll ans=(sum*(n+1)/k)%mod;
47             cout<<ans<<endl;
48             return 0;
49         }
50         ll c1=mypow(ss,(n+1)/k)%mod;
51         ll c2=(c1-1+mod)%mod;
52         sum=((sum)*c2)%mod;
53         sum=(sum*mypow((ss-1+mod)%mod,mod-2))%mod;
54     }
55    cout << (sum+mod)%mod<<endl;
56     return 0;
57 }
View Code

猜你喜欢

转载自www.cnblogs.com/MekakuCityActor/p/9917963.html