1. 程式人生 > >codevs 2314 數學作業

codevs 2314 數學作業

class 其中 block amp namespace memset int tmp oid

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 想了大半天終於意識到這是一道不可能手算出來的題目,於是他只好向你求助,希望 你能編寫一個程序幫他解決這個問題。

輸入描述 Input Description

只有一行 為用空格隔開的兩個正整數 N 和 M

輸出描述 Output Description

僅包含一個非負整數,表示 Concatenate (1 .. N ) Mod M 的值

樣例輸入 Sample Input

13 13

樣例輸出 Sample Output

4

數據範圍及提示 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 數學作業