【bzoj3122】: [Sdoi2013]随机数生成器 数论-BSGS

【bzoj3122】: [Sdoi2013]随机数生成器

当a>=2 化简得 

 

然后 BSGS 求解

其他的特判 :

当 x=t  n=1

当 a=1 

当 a=0 判断b==t

 1 /* http://www.cnblogs.com/karl07/ */
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <map>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 #define LL long long
11 int T;
12 LL a,b,x,t,p;
13 
14 LL Q_pow(LL x,LL y,LL p){
15     LL ans=1;
16     while (y){
17         if (y&1) ans=ans*x%p; 
18         x=x*x%p; y=(y>>1);
19     }
20     return ans;
21 }
22 
23 LL BSGS(LL a,LL b,LL p){
24     if ((a==0 && b!=0) || (a==1 && b!=1)) return -2;
25     map<LL,LL> x;
26     LL sz=ceil(sqrt(p)),k=1,inv;
27     x.clear();
28     x[1]=0; inv=Q_pow(Q_pow(a,sz,p),p-2,p);
29     for (int i=1;i<sz;i++){
30         k=k*a%p;
31         if (!x.count(k)) x[k]=i;
32     }
33     for (int i=0;i<sz;i++){
34         if (x.count(b)) return i*sz+x[b];
35         b=b*inv%p;
36     }
37     return -2;
38 }
39 
40 int main(){
41     scanf("%d",&T);
42     for (int tt=1;tt<=T;tt++){
43         scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x,&t);
44         if (x==t) {
45             puts("1");
46         }else{
47             if (a==0) {
48                 printf("%d\n",b==t ? 2 : -1);
49             }
50             if (a==1) {
51                 printf("%lld\n",b==0 ? -1 : (t-x+p)%p*Q_pow(b,p-2,p)%p+1);
52             }
53             if (a>=2){
54                 LL inv=Q_pow(a-1,p-2,p);
55                 b=b*inv%p;
56                 t=(t+b)%p;
57                 x=(x+b)%p;
58                 t=t*Q_pow(x,p-2,p)%p;
59                 printf("%lld\n",BSGS(a,t,p)+1);
60             }
61         }
62     }
63     return 0;
64 }
View Code

 

posted @ 2017-03-19 16:11  karl07  阅读(130)  评论(0编辑  收藏  举报