bzoj 2326: [HNOI2011]数学作业

Description

小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题:给定正整数 N 和 M
要求计算 Concatenate (1 .. N) Mod M 的值,其中 Concatenate (1 ..N)是将所有正整数 1, 2, …, N 顺序连接起来得到的数。
例如,N = 13, Concatenate (1 .. N)=12345678910111213.小C 想了大半天终于意识到这是一道不可能手算出来的题目,
于是他只好向你求助,希望你能编写一个程序帮他解决这个问题。
 

Input

只有一行且为用空格隔开的两个正整数N和M,
1≤N≤10^18且1≤M≤10^9.

Output

仅包含一个非负整数,表示 Concatenate (1 .. N) Mod M 的值。

Sample Input

13 13

Sample Output

4
 
思路: 分段做矩阵乘法
我们有
(f[n] n 1)=(f[n-1] n-1 1)* (10^k 0 0 
                                        1     1 0
                                         1    1 1 )
所以我们可以按照k分段,k表示数字的位数
 1 #include<bits/stdc++.h>
 2 using namespace std; 
 3 
 4 #define F(i,a,b) for(int i=a;i<=b;i++) 
 5 #define D(i,a,b) for(int i=a;i>=b;i--) 
 6 #define ms(i,a)  memset(a,i,sizeof(a)) 
 7 #define LL       long long 
 8 template<class T>void read(T &x){
 9     x=0; char c=getchar(); 
10     while (!isdigit(c)) c=getchar(); 
11     while (isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar(); 
12 }
13 template<class T>void write(T x){
14     if(x>9) write(x/10); 
15     putchar(48+x%10); 
16 }
17 
18 LL n,m,pw[20],pwm[20]; 
19 
20 struct Matrix{
21     int x[3][3];  
22     Matrix operator *(Matrix const &t)const{
23         Matrix y; ms(0,y.x);  
24         F(i,0,2)F(j,0,2)F(k,0,2) y.x[i][j]=(y.x[i][j]+(LL)x[i][k]*t.x[k][j]) % m;  
25         return y;  
26     }
27     Matrix operator^(LL k){
28         Matrix ans,tmp;  
29         ms(0,ans.x);  
30         F(i,0,2) F(j,0,2) tmp.x[i][j]=x[i][j];  
31         F(i,0,2) ans.x[i][i]=1;  
32         while (k){
33             if(k&1) ans=ans*tmp; 
34             tmp=tmp*tmp;  
35             k>>=1; 
36         }
37         return ans; 
38     }
39 }; 
40 
41 int main(){
42     read(n); 
43     read(m);  
44     int len=0; 
45     LL k=n;  
46     while (k){
47         len++; 
48         k/=10;   
49     }
50     pw[0]=1;
51     pwm[0]=1%m;  
52     F(i,1,19) pw[i]=pw[i-1]*10,pwm[i]=pwm[i-1]* 10% m;  
53     LL ans=0;  
54     F(i,1,len-1) {
55         Matrix t;  
56         ms(0,t.x); 
57         t.x[0][0]=pwm[i];  
58         t.x[1][0]=t.x[1][1]=1; 
59         t.x[2][0]=t.x[2][1]=t.x[2][2]=1; 
60         t=t^(pw[i]-pw[i-1]);  
61         ans=(ans*t.x[0][0]+(pwm[i-1]-1)*t.x[1][0]+t.x[2][0])% m;  
62     }
63     Matrix t; 
64     ms(0,t.x);  
65     t.x[0][0]=pwm[len];  
66     t.x[1][0]=t.x[1][1]=1; 
67     t.x[2][0]=t.x[2][1]=t.x[2][2]=1;  
68     t=t^(n-pw[len-1]+1); 
69     ans=(ans*t.x[0][0]+(pwm[len-1]-1)*t.x[1][0]+t.x[2][0]) % m;
70     write(ans); 
71     return 0; 
72 }

 

posted @ 2018-10-24 14:52  zjxxcn  阅读(129)  评论(0编辑  收藏  举报