codevs 2314 數學作業
阿新 • • 發佈:2017-06-04
class 其中 block amp namespace memset int tmp oid
輸入描述 Input Description
2314 數學作業
2011年省隊選拔賽湖南
時間限制: 1 s 空間限制: 128000 KB 題目等級 : 大師 Master 題目描述 Description小 C 數學成績優異,於是老師給小 C 留了一道非常難的數學作業題: 給定正整數 N 和 M ,要求計算 Concatenate (1 .. N ) Mod M 的值,其中Concatenate (1 .. N ) 是將所有正整數 1, 2, …, N 順序連接起來得到的數。例如, N = 13, Concatenate (1 .. N ) = 12345678910111213. 小 C 想了大半天終於意識到這是一道不可能手算出來的題目,於是他只好向你求助,希望 你能編寫一個程序幫他解決這個問題。
只有一行 為用空格隔開的兩個正整數 N 和 M
輸出描述 Output Description僅包含一個非負整數,表示 Concatenate (1 .. N ) Mod M 的值
樣例輸入 Sample Input13 13
樣例輸出 Sample Output4
數據範圍及提示 Data Size & Hint其中 30%的數據滿足1≤ N ≤1000000;100%的數據滿足1≤ N ≤1018且1≤ M ≤109
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef int matrix[3][3]; typedef long long ll; ll N; int MOD; matrix mat,Q,tmp; void Init_matrix(){ memset(mat,0,sizeof(mat)); mat[0][1]=mat[0][2]=mat[1][1]=mat[1][2]=mat[2][2]=1; memset(Q,0,sizeof(Q)); for(int i=0;i<3;i++)Q[i][i]=1; } void Mul(matrix &a,matrix &b){ memset(tmp,0,sizeof(tmp)); for(int i=0;i<3;i++) for(int k=0;k<3;k++) for(int j=0;j<3;j++) if((tmp[i][j]+=ll(a[i][k])*b[k][j]%MOD)>=MOD) tmp[i][j]-=MOD; memcpy(a,tmp,sizeof(a)); } void Power(matrix &a,matrix &b,ll k){ while(k){if(k&1)Mul(a,b);k>>=1;Mul(b,b);} } int main(){ scanf("%lld%d",&N,&MOD); int len=0,B=0,C=0; ll p=1; for(ll t=N;t;t/=10,len++); for(int i=1;i<len;i++){ Init_matrix(); mat[0][0]=(p=p*10)%MOD; Power(Q,mat,p-p/10); B=(ll(B)*Q[0][0]%MOD+ll(C)*Q[0][1]%MOD+Q[0][2])%MOD; C=((p%MOD)-1+MOD)%MOD; } Init_matrix(); mat[0][0]=p*10%MOD; Power(Q,mat,N-p+1); B=(ll(B)*Q[0][0]%MOD+ll(C)*Q[0][1]%MOD+Q[0][2])%MOD; printf("%d\n",B); return 0; }
codevs 2314 數學作業