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