首页 > 代码库 > codevs 2314 数学作业
codevs 2314 数学作业
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 数学作业
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。