标签:
首先,列方程
我们定义s[i] = 10 ^ ((int) log(i))
于是,f[i] = (f[i - 1] * s[i] + i) % p
反正总之就是个沙茶递推
然后我们来看优化。。。怎么感觉像矩阵乘法呢?
发现要按照log(i)即i的位数分类讨论,在相同位数的时候令矩阵为
s[i] 0 0
1 1 0
0 1 1
即可
1 /************************************************************** 2 Problem: 2326 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:16 ms 7 Memory:808 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 12 using namespace std; 13 typedef long long ll; 14 15 ll n, p; 16 17 struct Matrix { 18 ll x[4][4]; 19 20 Matrix (int X) { 21 int i, j; 22 for (i = 1; i <= 3; ++i) 23 for (j = 1; j <= 3; ++j) 24 if (i == j) x[i][j] = X; 25 else x[i][j] = 0; 26 } 27 28 ll* operator [] (int X) { 29 return x[X]; 30 } 31 }; 32 33 inline void operator *= (Matrix &x, Matrix y) { 34 int i, j, k; 35 Matrix res(0); 36 for (i = 1; i <= 3; ++i) 37 for (j = 1; j <= 3; ++j) 38 for (k = 1; k <= 3; ++k) 39 (res[i][j] += x[i][k] * y[k][j]) %= p; 40 x = res; 41 }; 42 43 Matrix pow(Matrix x, ll y) { 44 Matrix res(1); 45 while (y) { 46 if (y & 1) res *= x; 47 x *= x, y >>= 1; 48 } 49 return res; 50 } 51 52 int main() { 53 ll i; 54 Matrix ans(1), a(0); 55 scanf("%lld%lld", &n, &p); 56 a[1][1] = 10 % p, a[2][1] = a[2][2] = a[3][2] = a[3][3] = 1; 57 for (i = 10; i <= n; i *= 10, a[1][1] = i % p) 58 ans *= pow(a, i - i / 10); 59 ans *= pow(a, n - i / 10 + 1); 60 printf("%lld\n", (ans[2][1] + ans[3][1]) % p); 61 return 0; 62 }
标签:
原文地址:http://www.cnblogs.com/rausen/p/4175633.html