P2044 [NOI2012]随机数生成器

洛咕原题

正常的矩乘题。

但是,计算过程中会爆long long。

所以,我们要用快速(龟速)乘来解决。

快速乘,也就是把快速幂稍作修改。乘法被分成若干个加法,以时间为代价解决精度问题。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;

ll n,m,_a,c,g;
inline ll fastmul(ll x,ll y){ //快速乘
    ll ans=0;
    for(;y;y>>=1){
        if(y&1) ans=(ans+x)%m;
        x=(x<<1)%m;
    }
    return ans%m;
}
struct matrix{
    ll a[3][3];
    matrix(){memset(a,0,sizeof(a));}
    matrix operator * (matrix &tmp){
        matrix c;
        for(int i=1;i<=2;++i)
            for(int j=1;j<=2;++j)
                for(int k=1;k<=2;++k)
                    c.a[i][j]=(c.a[i][j]+fastmul(a[i][k],tmp.a[k][j]))%m;
        return c;
    }
    matrix ksm(matrix x,ll y){
        matrix ans;
        ans.a[1][1]=ans.a[2][2]=1;
        for(;y;y>>=1){
            if(y&1) ans=ans*x;
            x=x*x;
        }
        return ans;
    }
}p,st;

int main()
{
    scanf("%lld%lld%lld%lld%lld%lld",&m,&_a,&c,&st.a[1][1],&n,&g);
    p.a[1][1]=_a; p.a[2][1]=p.a[2][2]=1; //构造初始矩阵
    st.a[1][2]=c;
    p=p.ksm(p,n);
    st=st*p;
    printf("%lld",st.a[1][1]%g);
    return 0;
}

 

posted @ 2018-08-23 19:38  kafuuchino  阅读(186)  评论(0编辑  收藏  举报