P2044 [NOI2012]随机数生成器

传送门

很显然可以递推

前一项可以推出后一项

但是数据太大

那就考虑矩阵优化

那么构造一个初始矩阵:[ x[0]  , 1 ]

然后构造一个转移矩阵:[ a   ,  0 ]

              [ c   ,  1 ]

然后就可以了

看到这里的大佬应该都会矩阵优化吧...

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll n,m,c,g;
inline ll fastmul(ll x,ll y)
{
    ll ans=0;
    while(y)
    {
        if(y&1) ans=(ans+x)%m;
        x=(x<<1)%m;
        y>>=1;
    }
    return ans;
}
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;
        while(y)
        {
            if(y&1) ans=ans*x;
            x=x*x;
            y>>=1;
        }
        return ans;
    }
}p,st;

int main()
{
    scanf("%lld%lld%lld%lld%lld%lld",&m,&p.a[1][1],&p.a[2][1],&st.a[1][1],&n,&g);
    st.a[1][2]=p.a[2][2]=1;
    p=p.ksm(p,n);
    st=st*p;
    printf("%lld",st.a[1][1]%g);
    return 0;
}

 

posted @ 2018-09-03 22:19  LLTYYC  阅读(224)  评论(0编辑  收藏  举报