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; }