• 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

  • 相关阅读:
    Swing编程基础 之二
    数据库有几种
    世界上所有的电脑操作系统
    Linux基础命令-有关于目录的命令
    Oracle Flashback 闪回
    Linux CentOS6.5下安装Oracle ASM
    如何将U盘内文件拷入VMware Linux CentOS6.5虚拟机
    iptables 开启端口
    在Oracle SQLplus下建用户 建表
    Linux CentOS中使用SQL*Plus启动和关闭数据库
  • 原文地址:https://www.cnblogs.com/xydddd/p/5309057.html
Copyright © 2020-2023  润新知