Luogu2044 [NOI2012]隨機數生成器
阿新 • • 發佈:2020-07-26
https://www.luogu.com.cn/problem/P2044
矩陣快速冪
\[X_{n+1}=aX_{n}+c\\ \begin{cases} X_{n+1}=aX_{n}+1*c\\ c=0*X_{n}+1*c \end{cases} \]
但是模數有點大(\(10^{18}\)),會爆\(long\quad long\)
雖然可以__int128跑過去
#include<cstdio> #include<iostream> #define n 2 #define ll __int128 using namespace std; ll m,a,c,X0,N,g; struct mat { ll f[n+1][n+1]; mat operator *(mat b) { mat c; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) c.f[i][j]=0; for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) c.f[i][j]=(c.f[i][j]+f[i][k]*b.f[k][j])%m; return c; } }zero,ans,cs,zy; __int128 read() { __int128 s=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) { s=(s << 3)+(s << 1)+(c^48); c=getchar(); } return s; } void write(__int128 x) { if (x>=10) write(x/10); putchar(x%10+48); } mat ksm(mat x,ll y) { mat ans=zero; while (y) { if (y&1) ans=ans*x; x=x*x; y >>=1; } return ans; } int main() { for (int i=1;i<=n;i++) zero.f[i][i]=1; m=read(),a=read(),c=read(),X0=read(),N=read(),g=read(); cs.f[1][1]=X0,cs.f[2][1]=c; zy.f[1][1]=a,zy.f[1][2]=1,zy.f[2][2]=1; ans=ksm(zy,N)*cs; write(ans.f[1][1]%g),putchar('\n'); return 0; }