您的位置:首页 > 其它

bzoj2875 [noi2012]随机数生成器(矩阵倍增)

2017-08-10 23:31 309 查看
挺裸的矩阵倍增。。。就是再处理一下ll*ll.思想类似快速幂,例如对x*y,把x变成二进制,y去倍增,每次都mod m,变乘法为许多次加法,保证不会溢出。

#include <cstdio>
#include <cstring>
#define ll long long
ll g,aa,c,x0,n,mod;
inline ll mul(ll x,ll y){//ll*ll的处理
ll res=0;
for(;x;x>>=1,y=(y+y)%mod)
if(x&1) res=(res+y)%mod;
return res;
}
struct matrix{
ll mat[2][2];
matrix(bool op){
memset(mat,0,sizeof(mat));
if(op) mat[0][0]=1,mat[1][1]=1;
}
matrix operator*(matrix b){
matrix res(0);
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
fo
1183f
r(int k=0;k<2;++k)
res.mat[i][j]=(res.mat[i][j]+mul(mat[i][k],b.mat[k][j]))%mod;
return res;
}
matrix operator^(ll k){
matrix res(1);matrix b(0);
memcpy(b.mat,mat,sizeof(mat));
for(;k;k>>=1,b=b*b)
if(k&1) res=res*b;
return res;
}
}trans(0),a(0);
int main(){
//  freopen("a.in","r",stdin);
scanf("%lld%lld%lld%lld%lld%lld",&mod,&aa,&c,&x0,&n,&g);
a.mat[0][0]=x0;a.mat[0][1]=c;
trans.mat[0][0]=aa;trans.mat[1][1]=trans.mat[1][0]=1;
a=a*(trans^n);
printf("%lld\n",a.mat[0][0]%g);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: