zoukankan      html  css  js  c++  java
  • bzoj 3122: [Sdoi2013]随机数生成器

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<map>
      4 #include<cmath>
      5 #define ll long long
      6 using namespace std;
      7 ll T,p,a,b,c,x1,t;
      8 map<ll,ll> mp;
      9 ll exgcd(ll b,ll p,ll &x,ll &y)
     10 {
     11     if(!p)
     12       {
     13         x=1;
     14         y=0;
     15         return b;
     16       }
     17     ll t1=exgcd(p,b%p,x,y);
     18     ll t=x;
     19     x=y;
     20     y=t-b/p*y;
     21     return t1;
     22 }
     23 ll kuai(ll a,ll k,ll p)
     24 {
     25     ll ans=1;
     26     for(;k;)
     27       {
     28         if(k%2)
     29           ans=(ans*a)%p;
     30         k/=2;
     31         a=(a*a)%p;
     32       }
     33     return ans;
     34 }
     35 ll pan(ll y,ll z,ll p)
     36 {
     37     mp.clear();
     38     ll m=ceil(sqrt(p)),t=1;
     39     mp[1]=m+1;
     40     for(ll i=1;i<m;i++)
     41         {
     42            t=t*y%p;
     43            mp[t]=i;
     44         }
     45     ll T=kuai(y,p-m-1,p),ine=1;
     46     for(ll k=0;k<=m;k++)
     47        {
     48            ll i=mp[z*ine%p];
     49            if(i)
     50               {
     51                 if(i==m+1)
     52                   i=0;
     53                 return k*m+i+1;
     54               } 
     55           ine=ine*T%p;
     56        }
     57     return -1;
     58 }
     59 ll solve()
     60 {
     61     if(x1==t) 
     62       return 1;
     63     if(a==0)
     64       {
     65         if(b==t)
     66           return 2;
     67         return -1;
     68       }
     69     if(a==1)
     70       {
     71         c=(t-x1+p)%p;
     72         ll x,y;
     73         ll t1=exgcd(b,p,x,y);
     74         if(c%t1)
     75           return -1;
     76         c/=t1;
     77         x=x*c%p;
     78         for(;x<0;x+=p);
     79         return x+1;
     80       }
     81     if(a>1)
     82       {
     83         c=kuai(a-1,p-2,p);
     84         ll x,y,d=(b*c+t)%p;
     85         ll t1=exgcd((x1+b*c)%p,p,x,y);
     86         if(d%t1)
     87           return -1;
     88         d/=t1;
     89         x=x*d%p;
     90         for(;x<0;x+=p);
     91         a%=p;
     92         x%=p;
     93         if(!a&&!x)
     94           return 2;
     95         if(!a)
     96           return -1;
     97         return pan(a,x,p);
     98       }
     99 }
    100 int main()
    101 {
    102     scanf("%lld",&T);
    103     for(int i=1;i<=T;i++)
    104       {
    105         scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x1,&t);
    106         printf("%lld
    ",solve());
    107       }
    108     return 0;
    109 }

    当 a==0时,判断b,当a==1时,exgcd否则BSGS

  • 相关阅读:
    OSI安全体系结构
    PHP 二维数组根据相同的值进行合并
    Java实现 LeetCode 17 电话号码的字母组合
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 14 最长公共前缀
  • 原文地址:https://www.cnblogs.com/xydddd/p/5309057.html
Copyright © 2011-2022 走看看