[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 }