题目背景
nodgd是一个喜欢写程序的同学,前不久洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题。于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家……
题目描述
洛谷OJ当然算是好地方,nodgd同学打算和朋友分享一下。于是他就拉上了他的朋友Ciocio和Nicole两位同学一起刷题。喜欢比赛的他们当然不放过这样一次刷题比赛的机会!
在第1天nodgd,Coicoi,Nicole都只做了1道题。
在第2天nodgd,Coicoi,Nicole都只做了3道题。
他们都有着严格的刷题规则,并且会在每一天都很遵守规则的刷一定量的题。
(1)nodgd同学第k+2天刷题数量a[k+2]=p*a[k+1]+q*a[k]+b[k+1]+c[k+1]+r*k^2+t*k+1;
(2)Ciocio同学第k+2天刷题数量b[k+2]=u*b[k+1]+v*b[k]+a[k+1]+c[k+1]+w^k;
(3)Nicole同学第k+2天刷题数量c[k+2]=x*c[k+1]+y*c[k]+a[k+1]+b[k+1]+z^k+k+2;
(以上的字母p,q,r,t,u,v,w,x,y,z都是给定的常数,并保证是正整数)
于是他们开始了长时间的刷题比赛!一共进行了N天(4<=N<=10^16)
但是时间是可贵的,nodgd想快速知道第N天每个人的刷题数量。不过nodgd同学还有大量的数学竞赛题、物理竞赛题、英语竞赛题、美术竞赛题、体育竞赛题……要做,就拜托你来帮他算算了。
由于结果很大,输出结果mod K的值即可。
输入输出格式
输入格式:
第一行两个正整数N,K。(4<=N<=10^16,2<=K<=10^16)
第二行四个正整数p,q,r,t。
第三行三个正整数u,v,w。
第四行三个正整数x,y,z。
(保证p,q,r,t,u,v,w,x,y,z都是不超过100的正整数)
输出格式:
共三行,每行一个名字+一个空格+一个整数。依次是nodgd,Ciocio,Nicole和他们在第N天刷题数量mod K的值。
输入输出样例
4 10007 2 1 1 1 2 2 3 1 1 2
nodgd 74 Ciocio 80 Nicole 59
说明
矩阵乘法。
注意,中间相乘过程可能会比64位长整型的数据范围还要大。
/* 矩阵稍微有点难搞,不过也是可以推出来。 注意要用慢速乘。 */ #include<iostream> #include<cstdio> #include<cstring> #define ll long long using namespace std; ll n,mod,p,q,r,t,u,v,w,x,y,z; ll f[12][12],a[12][12]; ll slow_mul(ll a,ll b){ ll ans=0; while(b){ if(b&1){ b--;ans+=a;ans%=mod; } a<<=1;a%=mod;b>>=1; } return ans; } void mul(ll a[12][12],ll b[12][12]){ ll c[12][12];memset(c,0,sizeof(c)); for(int i=1;i<=11;i++) for(int j=1;j<=11;j++) for(int k=1;k<=11;k++) c[i][j]=(c[i][j]+slow_mul(a[i][k],b[k][j]))%mod; for(int i=1;i<=11;i++) for(int j=1;j<=11;j++) a[i][j]=c[i][j]; } int main(){ cin>>n>>mod>>p>>q>>r>>t>>u>>v>>w>>x>>y>>z;n-=2; f[1][1]=f[1][3]=f[1][5]=3;f[1][2]=f[1][4]=f[1][6]=1; f[1][7]=f[1][8]=f[1][9]=1;f[1][10]=w;f[1][11]=z; a[1][1]=p;a[2][1]=q;a[7][1]=r;a[8][1]=t;a[3][3]=u; a[4][3]=v;a[5][5]=x;a[6][5]=y;a[9][5]=a[8][7]=2; a[10][10]=w;a[11][11]=z; a[1][2]=a[1][3]=a[1][5]=a[3][1]=a[3][4]=a[3][5]=1; a[5][1]=a[5][3]=a[7][7]=a[8][5]=a[8][8]=a[9][1]=1; a[9][7]=a[9][8]=a[9][9]=a[10][3]=a[11][5]=a[5][6]=1; while(n){ if(n&1)mul(f,a); mul(a,a);n>>=1; } cout<<"nodgd"<<" "<<f[1][1]<<endl; cout<<"Ciocio"<<" "<<f[1][3]<<endl; cout<<"Nicole"<<" "<<f[1][5]<<endl; return 0; }