BZOJ 3122: [Sdoi2013]随机数生成器 ex_gcd+BSGS

来源:互联网 发布:免费数据库有哪些 编辑:程序博客网 时间:2024/06/06 08:46

传送门(^__^) 嘻嘻……
我们可以得出一个等式
(t+b/(a-1))/(x1+b/(a-1))=a^(n-1) mod p
然后我们可以发现,这是一个形如B=A^n mod C的等式,于是用BSGS求出n-1即可
因为是在mod意义下做除法,所以我们需要用到ex_gcd
详细讲解请见http://www.cnblogs.com/yuiffy/p/3877381.html


代码如下:(内含数据哦O(∩_∩)O哈!)

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<map>#define int long longusing namespace std;map<int,int> mp; int cas,p,a,b,x1,t;int  ex_gcd(int aa,int bb,int &x,int &y){    if(bb==0)        return x=1,y=0,aa;    int s=ex_gcd(bb,aa%bb,x,y),temp=x;    x=y,y=temp-aa/bb*y;    return s;}signed main(void){    scanf("%lld",&cas);    while(cas--){        mp.clear();        scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x1,&t);        if(x1==t){            cout<<1<<endl;            continue;        }        if(a==0){            if(b==t){                cout<<2<<endl;                continue;            }            else{                cout<<-1<<endl;                continue;            }        }        if(a==1){            if(b==0){                cout<<-1<<endl;                continue;            }            else{                int x,y,ans;                ex_gcd(b,p,x,y);                ans=((((t-x1+p)%p)*x)%p+p)%p;                cout<<ans+1<<endl;                continue;            }        }        int A=a,B,ans=-1,s,m=sqrt(p),temp1,temp2,x,y;        ex_gcd(a-1,p,x,y),temp1=x;        ex_gcd((x1+b*temp1%p+p)%p,p,x,y),temp2=x;        B=(((t+b*temp1%p+p)%p)*temp2%p+p)%p;        m+=p-m*m!=0,s=1;         for(int j=0;j<m;j++)            mp[s]=j+1,s=((s*A)%p+p)%p;        int D=1;//此时s已经是A^m         for(int i=0;i<m;i++){            ex_gcd(D,p,x,y);            x=((x*B)%p+p)%p;            y=mp[x]-1;            if(y!=-1){                ans=i*m+y;                break;            }            D=((D*s)%p+p)%p;        }        cout<<(ans==-1 ? ans : ans+1)<<endl;    }    return 0;}/*507 0 4 6 667 0 18 24 2411 0 10 4 1029 0 3 17 341 0 1 36 2729 0 20 24 2259 1 0 17 1779 1 0 76 7659 1 0 11 5637 1 0 4 2029 1 10 18 2679 1 11 48 1523 1 1 1 1331 1 30 0 667 1 54 44 3853 1 44 30 5247 44 0 0 05 4 0 0 023 22 0 0 1567 59 0 0 3329 23 6 4 2759 47 38 26 4429 9 27 4 617 5 8 2 929 28 15 11 2243 15 33 0 177 3 1 5 129 14 24 8 2341 35 28 22 067 16 50 30 3729 19 25 17 2271 0 12 7 3467 58 5 48 4279 18 55 49 3679 49 33 26 7267 65 8 38 225 3 3 4 311 3 4 4 92 1 1 0 161 38 46 57 443 37 36 1 1767 57 30 63 737 2 35 27 2283 58 18 15 1267 0 57 25 459 40 6 42 4631 19 4 3 1729 23 14 26 215 2 3 4 029 17 25 3 23*//*1122-1-111-1-125771326532811-1-1313-116-1-142017625-12-1-1-13-1214-1131656-136-1-13-1*/

by >o< neighthorn

1 0