[BZOJ2875]NOI2012随机数生成器|矩阵乘法

来源:互联网 发布:linux yes命令 编辑:程序博客网 时间:2024/05/15 00:37

  一开始想用等比数列公式搞,但是模数可能为合数。。然后裸上矩乘,注意要用快速乘要不然会爆long long。

#include<cstdio>#include<iostream>#include<cmath>#include<memory.h>#define ll long longusing namespace std;ll m,a,c,x0,n,g,an;struct ju{    ll a[2][2];    int n,m;}ans,t;ll mul(ll a,ll b){    if (b>a) swap(a,b);    if (b==0) return 0ll;    ll c=mul(a,b/2);    c=(c+c)%m;    if (b%2==1) c=(c+a)%m;    return c;}ju operator*(ju a,ju b){    ju ans;    memset(ans.a,0,sizeof(ans.a));    ans.n=a.n;ans.m=b.m;    for (int i=0;i<a.n;i++)        for (int j=0;j<b.n;j++)            for (int k=0;k<b.m;k++)                ans.a[i][k]=(ans.a[i][k]+mul(a.a[i][j],b.a[j][k]))%m;    return ans;}ju pow(ju a,ll b){    if (b==1) return a;    ju c=pow(a,b/2);    c=c*c;    if (b%2==1) c=c*a;    return c;}int main(){    scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x0,&n,&g);    t.a[0][0]=1ll;t.a[0][1]=0ll;t.a[1][0]=1ll;t.a[1][1]=a;t.n=2;t.m=2;    ans.a[0][0]=c;ans.a[1][0]=x0;ans.n=2;ans.m=1;    ans=pow(t,n)*ans;    cout<<ans.a[1][0]%g;}
0 0
原创粉丝点击