[NOI2013]矩陣遊戲

題意:ide

給定一次函數遞推式,求第n項。n <= 1e(1e6)函數

解:spa

這麼多位...code

咱們手動代入前幾項,就能發現:blog

這個的左邊能夠用歐拉定理降冪,右邊是個等比數列。字符串

而後咱們就能夠求出f[i][1]和f[i + 1][1]之間的一次遞推式了。get

同理求出f[1][1]和f[n][1]之間的關係,而後就OK了。string

如下這些點須要注意:io

公比可能爲1event

隨時取模!我就是在給等比數列求和函數傳參的時候沒有對首項取模致使只有15分...

第二次使用上面那個式子的時候注意全部的a和b都要隨之變化!

用字符串讀入nm,計算的時候逐位加起來同時取模。

 1 #include <cstdio>
 2 #include <cstring>
 3 typedef long long LL;
 4 
 5 const int N = 1000010;
 6 const LL MO = 1000000007;
 7 const LL phi = 1000000006;
 8 
 9 char pn[N], pm[N];
10 LL a, b, c, d, m, n;
11 
12 inline LL qpow(LL A, LL B) {
13     LL ans = 1;
14     A %= MO;
15     while(B) {
16         if(B & 1) {
17             ans = ans * A % MO;
18         }
19         A = A * A % MO;
20         B = B >> 1;
21     }
22     return ans;
23 }
24 
25 inline LL getsum(char *A, LL p) {
26     int len = strlen(A);
27     LL ans = 0;
28     for(int i = 0; i < len; i++) {
29         ans = ((ans << 3) + (ans << 1) + A[i] - 48) % p;
30     }
31     return ans;
32 }
33 
34 inline LL Qget(LL a1, LL q, char *A) {
35     a1 %= MO;
36     q %= MO;
37     if(q == 1) {
38         m = getsum(A, MO);
39         m = ((m - 1) % MO + MO) % MO;
40         return m * a1 % MO;
41     }
42     //return a1 * (qpow(q, n) - 1) / (q - 1);
43     m = getsum(A, MO - 1);
44     m = ((m - 1) % (MO - 1) + (MO - 1)) % (MO - 1);
45     LL t = ((qpow(q, m) - 1) % MO + MO) % MO;
46     LL inv = qpow(q - 1, MO - 2);
47     return a1 * t % MO * inv % MO;
48 }
49 
50 int main() {
51     scanf("%s", pn);
52     scanf("%s", pm);
53     scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
54 
55     //LL s = qpow(a, n - 1);
56     m = getsum(pm, phi);
57     m = ((m - 1) % phi + phi) % phi;
58     LL s = qpow(a, m);
59     LL t = Qget(b, a, pm);
60     //printf("%lld %lld %lld %lld \n", s, t, s * c, c * t + d);
61 
62     //LL ss = qpow(s, m - 1);
63     n = getsum(pn, phi);
64     n = ((n - 1) % phi + phi) % phi;
65     LL ss = qpow(s * c, n);
66     LL tt = Qget(d + t * c, s * c, pn);
67     //printf("%lld %lld \n", ss, tt);
68 
69     LL ans = s * (ss + tt) % MO + t;
70     printf("%lld", ans % MO);
71 
72     return 0;
73 }
AC代碼
相關文章
相關標籤/搜索