[BZOJ 2875][Noi2012]随机数生成器:矩阵乘法+快速乘

来源:互联网 发布:淘宝面膜排行榜 编辑:程序博客网 时间:2024/05/17 06:41

点击这里查看原题

其实是个水题,坑点在于两个long long直接相乘会爆。long long的上限大概是2*1e18,而题目所给的数据不会超过1e18,因此可以使用快速乘。

/*User:SmallLanguage:C++Problem No.:2875*/#include<bits/stdc++.h>#define ll long long#define inf 999999999using namespace std;ll m,a,c,x,n,g;struct mat{    ll n,m,c[4][4];    mat(){        memset(c,0,sizeof(c));    }}f,b;ll mul(ll a,ll b){    ll res=0;    while(b){        if(b&1LL) res=(res+a)%m;        a=(a+a)%m;        b>>=1LL;    }    return res;}mat operator*(const mat a,const mat b){    mat c;    c.n=a.n;    c.m=b.m;    for(int i=1;i<=c.n;i++)        for(int j=1;j<=c.m;j++)            for(int k=1;k<=a.m;k++)                c.c[i][j]=(c.c[i][j]+mul(a.c[i][k],b.c[k][j]))%m;    return c;}mat pow(mat a,ll b){    mat res;    res.n=res.m=a.n;    for(int i=1;i<=res.n;i++) res.c[i][i]=1;    while(b){        if(b&1LL) res=res*a;        a=a*a;        b>>=1LL;    }    return res;}int main(){    freopen("data.in","r",stdin);//    scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x,&n,&g);    f.n=1,f.m=2;    f.c[1][1]=x;    f.c[1][2]=c;    b.n=b.m=2;    b.c[1][1]=a;    b.c[2][1]=b.c[2][2]=1;    mat ans=f*pow(b,n);    printf("%lld\n",ans.c[1][1]%g);    return 0;}
0 0
原创粉丝点击