您的位置:首页 > 其它

【bzoj2875】随机数生成器(矩乘快速幂+快速乘)

2017-09-05 14:41 267 查看
题目:我是超链接

题解:

矩阵快速幂裸题?

初始化的矩阵|x0 c| 

准备乘的矩阵|a 0| 

                       |1 1| 

这样就会发现是正确的,最后两个点是爆longlong的,乘的时候需要用快速乘(与快速幂不同的地方就是把*变成+)

还有一件事,你只需要把矩阵求出来最后的最后%g,中间一直要%m(kp)

一个自认为很优美的代码:

#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
LL m,aa,c,n,g,x;
struct hh{LL sq[5][5];void cl(){memset(sq,0,sizeof(sq));}}ans,mult,a;
LL mul(LL a,LL b){
LL res=0;
for(;b;b>>=1,a=(a+a)%m) if(b&1) res=(res+a)%m;
return res;
}
hh work(hh a,hh b)
{
int i,j,k;
hh c;c.cl();
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++)
c.sq[i][j]=(c.sq[i][j]+mul(a.sq[i][k],b.sq[k][j])%m)%m;
return c;
}
hh ksm(LL k)
{
hh a;a=mult;
for (;k;k>>=1,a=work(a,a))
if (k&1) mult=work(mult,a);
return mult;
}
int main()
{
int i,j,k;
scanf("%lld%lld%lld%lld%lld%lld",&m,&aa,&c,&x,&n,&g);
a.sq[1][1]=x; a.sq[1][2]=c;
mult.sq[1][1]=aa; mult.sq[1][2]=0; mult.sq[2][1]=1; mult.sq[2][2]=1;
if (n>1) mult=ksm(n-1);
for (i=1;i<=1;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++)
ans.sq[i][j]=(ans.sq[i][j]+mul(a.sq[i][k],mult.sq[k][j])%m)%m;
printf("%lld",ans.sq[1][1]%g);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: