zoukankan      html  css  js  c++  java
  • BZOJ 3122 [SDOI2013]随机数生成器 (BSGS)

    题目大意:略 洛谷传送门 BZOJ传送门

    观察式子$x_{i+1}=acdot x_{i}+b (mod;p)$

    我们能用欧几里得算法求解$ax=c(mod;b)$的线性同余方程问题

    还能用$BSGS$算法求解$a^{x}=c(mod;b)$的指数同余方程问题

    而式子里的$b$这一项显得十分棘手

    还记得等比数列吗,是数学老师教的

    考虑构造一个"等比数列”方便我们递推

    $(x_{i+1}+K)=acdot (x_{i}+K) (mod;p)$

    解得$K=frac{b}{a-1}$

    这样,原式化成了$A^{X}=B(mod;p)$的形式

    好像求出指数$x$就行了?

    于是乎这道题就变成了一个裸的$BSGS$问题?

    $a==0$的情况特判

    $a==1?$原式变成了等差数列,用$exgcd$求解线性同余方程即可

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define N1 400010
      6 #define M1 40010
      7 #define ll long long
      8 #define dd double
      9 #define cint const int 
     10 #define cll const long long 
     11 #define inf 23333333333333333ll
     12 using namespace std;
     13 
     14 int gcd(int a,int b){ if(!b) return a; return gcd(b,a%b); }
     15 void exgcd(ll a,ll b,ll &x,ll &y)
     16 {
     17     if(!b){ x=1; y=0; return; }
     18     exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y;
     19 }
     20 int P,A,B,X1,T,K;
     21 namespace S0{
     22 int solve()
     23 {
     24     int ans,g; ll inv,invy; T=(T-X1+P)%P;
     25     g=gcd(B,P); if(T%g!=0) return -1;
     26     T/=g; B/=g; P/=g; 
     27     exgcd(B,P,inv,invy); inv=(inv%P+P)%P;
     28     ans=inv*T%P; P*=g; ans=1ll*ans*g%P;
     29     return ans+1; 
     30 }
     31 };
     32 namespace S1{
     33 #define maxn 400000
     34 struct Hsh{
     35 int head[N1],to[M1],nxt[M1],val[M1],cte;
     36 void ins(int x,int w)
     37 {
     38     int u=x%maxn,j,v;
     39     for(j=head[u];j;j=nxt[j])
     40     {
     41         v=to[j];
     42         if(v==x) return;
     43     }
     44     cte++; to[cte]=x; nxt[cte]=head[u];
     45     head[u]=cte; val[cte]=w;
     46 }
     47 int find(int x)
     48 {
     49     int u=x%maxn,j,v;
     50     for(j=head[u];j;j=nxt[j])
     51     {
     52         v=to[j];
     53         if(v==x) return val[j];
     54     }
     55     return -1;
     56 }
     57 }h;
     58 ll qpow(ll x,ll y,cll &P)
     59 {
     60     ll ans=1;
     61     while(y){
     62         if(y&1) ans=ans*x%P;
     63         x=x*x%P; y>>=1;
     64     }return ans;
     65 }
     66 #undef maxn
     67 int solve(int p)
     68 {
     69     int i,j,sq;ll K,pw,now,ans,inv,invy,Y,tmp; cll P=p;
     70     exgcd(A-1,P,inv,invy); inv=(inv%P+P)%P; K=inv*B%P; 
     71     T=(T+K)%P; X1=(X1+K)%P;
     72     exgcd(X1,P,inv,invy); inv=(inv%P+P)%P; T=T*inv%P;
     73     sq=sqrt(P); 
     74     for(pw=qpow(A,sq,P),now=1,i=1;(i-1)*sq<P;i++)
     75     {
     76         now=1ll*now*pw%P;
     77         h.ins(now,i);
     78     }
     79     for(ans=inf,now=T,i=0;i<sq;i++)
     80     {
     81         tmp=h.find(now);
     82         if(tmp!=-1) ans=min(ans,tmp*sq-i);
     83         now=now*A%P;
     84     }
     85     memset(&h,0,sizeof(h));
     86     if(ans==inf) return -1;
     87     return ans+1;
     88 }
     89 };
     90 int Case;
     91 
     92 int main()
     93 {
     94     scanf("%d",&Case);
     95     while(Case--)
     96     {
     97         scanf("%d%d%d%d%d",&P,&A,&B,&X1,&T);
     98         if(X1==T){ puts("1"); continue; }
     99         if(A==0)
    100         {
    101             if(T==B) puts("2");
    102             else puts("-1");
    103             continue;
    104         }
    105         if(A==1) printf("%d
    ",S0::solve());
    106         else printf("%d
    ",S1::solve(P));
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    春招已近,这份GitHub万星的ML算法面试大全请收下
    [资源推荐] 必须收藏的两个查找论文和代码实现的网站!
    windows下安装pycocotools,亲测有效!
    GAN原理
    2018-07-02
    虚函数和纯虚函数
    友元
    string字符串
    实参和形参
    C/C++学习笔记汇总
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10251771.html
Copyright © 2011-2022 走看看