BZOJ 3122 SDOI2013 随机数生成器
公式就不推了.hzwer上的很清楚.
值得注意的一点是,如果最后答案成0,需要加上mod.否则400ms wa.
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<map> 5 6 using namespace std; 7 #define ll long long 8 #define FILE "dealing" 9 #define up(i,j,n) for(int i=j;i<=n;i++) 10 #define db long double 11 #define pii pair<int,int> 12 #define pb push_back 13 #define mem(a,L) memset(a,0,sizeof(int)*(L+1)) 14 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;} 15 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;} 16 template<class T> inline T squ(T a){return a*a;} 17 const ll maxn=2000100+10,MAXN=20200,limit=1e7,base=23; 18 int read(){ 19 int x=0,f=1,ch=getchar(); 20 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 21 while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 22 return x*f; 23 } 24 ll mod,a,b,x1,t; 25 void exgcd(ll a,ll b,ll& d,ll& x,ll& y){ 26 if(b==0){d=a;x=1,y=0;return;} 27 exgcd(b,a%b,d,x,y); 28 ll t=x; 29 x=y; 30 y=t-a/b*y; 31 } 32 ll qpow(ll a,ll b){ 33 ll ans=1; 34 while(b){ 35 if(b&1)ans=ans*a%mod; 36 a=a*a%mod; 37 b>>=1; 38 } 39 return ans; 40 } 41 ll BSGS(ll a,ll b){ 42 map<ll,int> t; 43 ll m=(int)sqrt(mod+1.0)+1; 44 ll inv=qpow(qpow(a,m),mod-2); 45 ll w=1; 46 for(int i=0;i<m;i++) 47 t[w]=i,w=(w*a)%mod; 48 for(int i=0;i<=m;i++){ 49 if(t.count(b))return t[b]+i*m; 50 b=b*inv%mod; 51 } 52 return -2; 53 } 54 int main(){ 55 freopen(FILE".in","r",stdin); 56 freopen(FILE".out","w",stdout); 57 int T=read(); 58 while(T--){ 59 mod=read(),a=read(),b=read(),x1=read(),t=read(); 60 if(t==x1){printf("1\n");continue;} 61 else if(a==0){printf("%lld\n",b==t?2LL:-1LL);continue;} 62 else if(a==1){ 63 ll x,y,d,c=(t-x1+mod)%mod; 64 exgcd(b,mod,d,x,y); 65 if(c%d){printf("-1\n");continue;} 66 x=x*(c/d); 67 x=(x%mod+1+mod)%mod; 68 if(x==0)x=mod; 69 printf("%lld\n",x); 70 } 71 else { 72 ll c=qpow(a-1,mod-2),x,y,d,sheng=(t+b*c%mod)%mod; 73 exgcd((x1+b*c%mod)%mod,mod,d,x,y); 74 if(sheng%d){printf("-1\n");continue;} 75 x=x*(sheng/d)%mod; 76 x=(x%mod+mod)%mod; 77 ll ans=(BSGS(a,x)+1)%mod; 78 if(ans==0)ans+=mod; 79 printf("%lld\n",ans); 80 } 81 } 82 return 0; 83 }