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

来源:互联网 发布:javascript中的date 编辑:程序博客网 时间:2024/05/01 04:01

题目:我是超链接

题解:

矩阵快速幂裸题?

初始化的矩阵|x0 c| 

准备乘的矩阵|a 0| 

                       |1 1| 

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

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

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

#include <cstdio>#include <cstring>#define LL long longusing 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);}


阅读全文
0 0