BZOJ3122: [Sdoi2013]随机数生成器

BSGS原来就是SB暴力。。。日了狗了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
#define ll long long
ll ex_gcd(ll &x,ll &y,ll a,ll b)
{
    if(b==0){x=1;y=0;return a;}
    ll c=ex_gcd(x,y,b,a%b),tp=x;
    x=y;y=tp-a/b*y;
    return c;
}
ll p,T;
char c;
inline void read(ll &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}

map<ll,ll>S;

int main()
{

    freopen("std.in","r",stdin);
    freopen("self.out","w",stdout);
    read(T);
    while(T--)
    {
        ll p,i,a,b,x1,t;
        ll xa,xp;
        read(p),read(a),read(b),read(x1),read(t);
        a%=p;
        if(t>=p){puts("-1");continue;}
        if(x1==t){puts("1");continue;}
        if(a==1)
        {
            if(b==0) 
              puts("-1");
            else
              {
                ll xi,yq;
                ll c=ex_gcd(xi,yq,b,p);
                if((t-x1)%c||c!=1)puts("-1");
                else printf("%lld\n",1+((xi*(t-x1)/c)%p+p)%p);
              }
            continue;
        }
        if(a==0)
        {
            if(t==b)puts("2");
            else puts("-1");continue;
        }
        ex_gcd(xa,xp,a-1,p);
        S.clear();
        xa%=p;
        xa+=p;
        xa%=p;
        ll xb;
        ex_gcd(xb,xp,x1+b*xa,p);
        xb%=p;
        xb+=p;
        xb%=p;
        ll right=((t+b*xa)%p)*xb;
        right%=p;
        right+=p;
        right%=p;
        ll size=sqrt(p)+1;
        ll tp=right;
        for(i=0;i<=size;i++,tp*=a,tp%=p)
          S[tp]=i+1;
        tp=a;
        ll left=1,ab=1;
        for(i=1;i<=size;i++)ab*=a,ab%=p;
        left=ab;
        for(i=1;i<=1+p/size;i++,left*=ab,left%=p)
          if(S[left]){
          printf("%lld\n",i*size-S[left]+2);goto asd;}
        puts("-1");
       asd:;
    }   
    return 0;
}

你可能感兴趣的:(BZOJ3122: [Sdoi2013]随机数生成器)