Codeforces 964C Alternating Sum

Alternating Sum

题意很简单 就是对一个数列求和。

题解:如果不考虑符号 每一项都是前一项的 (b/a)倍, 然后考虑到符号的话, 符号k次一循环, 那么 下一个同一符号的位置 就是 这一个位置的 (b/a)^k倍了, 然后我们可以发现这个是一个等比数列, 最后我们对等比数列求和就好了。

注意的就是 (b/a)^k % mod == 1的情况,我们可以将前K个数总和在一起, 在一起求等比的和就好了。

我们可以将公式 cir*(1-q^time) / (1 - q) 其中q = (b/a)^k 转化成 cir * (a1^(time*k) - b^(time*k)) / (a1^(time*k) - b^k * a ^((t-1)*k)) 然后因为要进行mod操作 所以 再转换成 cir * (a1^(time*k) - b^(time*k)) *inv( (a1^(time*k) - b^k * a ^((t-1)*k))) 就好了。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define ULL unsigned LL
 5 #define fi first
 6 #define se second
 7 #define lson l,m,rt<<1
 8 #define rson m+1,r,rt<<1|1
 9 #define max3(a,b,c) max(a,max(b,c))
10 #define min3(a,b,c) min(a,min(b,c))
11 typedef pair<int,int> pll;
12 const int INF = 0x3f3f3f3f;
13 const LL mod = 1e9+9;
14 const int N = 1e5+10;
15 int n, a, b, k;
16 char str[N];
17 LL qpow(int a, int b){
18     LL ret = 1;
19     while(b){
20         if(b&1) ret = (ret*a)%mod;
21         a = (a%mod*a%mod) % mod;
22         b >>= 1;
23     }
24     return ret%mod;
25 }
26 int main(){
27     scanf("%d%d%d%d",&n,&a,&b,&k);
28     scanf("%s", str);
29     int len = strlen(str);
30     LL ans = 0;
31     LL tmp, cir = 0;
32     for(int i = 0; i < len; i++){
33         tmp = qpow(a,n-i) * qpow(b,i) % mod;
34         if(str[i] == '+') {
35             cir += tmp;
36             cir %= mod;
37         }
38         else {
39             cir -= tmp;
40             if(cir < 0) cir += mod;
41             cir %= mod;
42         }
43     }
44     int time = (n+1) / len;
45     int lf = n+1 - len*time;   
46     int be = len*time;
47     for(int i = 0; be <= n; i++, be++){
48         tmp = qpow(a,n-be) * qpow(b,be) % mod;
49         if(str[i] == '+') {
50             ans += tmp;
51             ans %= mod;
52         }
53         else {
54             ans -= tmp;
55             if(ans < 0) ans += mod;
56             ans %= mod;
57         }
58     }
59     LL t1 = (qpow(a,len*time) - qpow(b,len*time))%mod;
60     if(t1 < 0) t1 += mod;
61     LL t2 = (qpow(a,len*time) % mod - qpow(b,len)*qpow(a,(time-1)*len)%mod) %mod;
62     if(t2 < 0) t2 += mod;
63     LL t3 = t1 *(qpow(t2,mod-2))% mod;
64     if(t2!=0){
65         ans = (ans + cir * t3 % mod)%mod;
66     }
67     else {
68         ans = (ans+cir*time%mod)%mod;
69     }
70     printf("%I64d", ans);
71     return 0  ;
72 }
73 /*
74 8 2 3 2
75 ++
76 */
View Code

 

posted @ 2018-04-18 13:59  Schenker  阅读(288)  评论(0编辑  收藏  举报