首页 > 代码库 > BZOJ 3122 SDOI2013 随机数生成器

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 }
View Code

 

BZOJ 3122 SDOI2013 随机数生成器