[NOI2012] 随机数生成器
看题,先骗分,直接模拟:
#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=800, INF=0x3f3f3f3f;
ll m,a,c,n,g;
ll x[10000000];
int main(){
cin>>m>>a>>c>>x[0]>>n>>g;
for(int i=1;i<=n;i++){
x[i]=(a*x[i-1]+c)%m;
}
cout<<x[n]%g<<endl;
return 0;
}
喜提 \(30Pts\)。
然后,也是很明显,因为是一个递推式,所以直接矩阵加速,找个转移矩阵就行(不过刚开始没找对,这个还得加强),然后矩阵快速幂求。
#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=800, INF=0x3f3f3f3f;
ll mod,a,c,X0,n,g;
ll ans[3][3];
ll A[3][3];
void f1(){
ll B[3][3]={0};
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
B[i][j]=(B[i][j]+(ans[i][k]%mod)*(A[k][j]%mod))%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
ans[i][j]=B[i][j];
}
void f2(){
ll B[3][3]={0};
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
B[i][j]=(B[i][j]+(A[i][k]%mod)*(A[k][j]%mod))%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
A[i][j]=B[i][j];
}
ll X(ll k){
A[1][1]=a;A[1][2]=0;A[2][1]=1;A[2][2]=1;
ans[1][1]=X0;ans[1][2]=c;
while(k>0){
if(k&1)f1();
f2();
k>>=1;
}
return ans[1][1]%g;
}
int main(){
cin>>mod>>a>>c>>X0>>n>>g;
cout<<X(n)<<endl;
return 0;
}
喜提\(60Pts\)。
然后确实不知道问题在哪了,根据题解,还要用快速乘,避免爆炸(雾
#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=800, INF=0x3f3f3f3f;
ll mod,a,c,X0,n,g;
ll ans[3][3];
ll A[3][3];
ll LowP(ll x,ll y){
ll ans=0;
while(y>0){
if(y&1){
ans+=x;
ans%=mod;
}
x+=x;
x%=mod;
y>>=1;
}
return ans;
}
void f1(){
ll B[3][3]={0};
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
B[i][j]=(B[i][j]+LowP(ans[i][k]%mod,A[k][j]%mod))%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
ans[i][j]=B[i][j];
}
void f2(){
ll B[3][3]={0};
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
B[i][j]=(B[i][j]+LowP(A[i][k]%mod,A[k][j]%mod))%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
A[i][j]=B[i][j];
}
ll X(ll k){
A[1][1]=a;A[1][2]=0;A[2][1]=1;A[2][2]=1;
ans[1][1]=X0;ans[1][2]=c;
while(k>0){
if(k&1)f1();
f2();
k>>=1;
}
return ans[1][1]%g;
}
int main(){
cin>>mod>>a>>c>>X0>>n>>g;
cout<<X(n)<<endl;
return 0;
}
喜提\(100Pts\)。