zoukankan      html  css  js  c++  java
  • [SDOI2013]随机数生成器

    https://www.zybuluo.com/ysner/note/1300007

    题面

    都过来看题解了,应该知道题面是什么吧

    解析

    好像还是(BSGS)模板题。
    虽然说我不看标签还不一定能意识到要用bsgs

    看到递推式之类的,应该要想到矩乘或者某些数学理论。。。
    题目的问题矩乘处理不了。
    也只能(BSGS)

    设第(n)天读到第(t)页。
    想想怎么把未知数弄到指数那里去。
    数学必修五中常常给出递推式,要我们证一个玩意儿是等比数列。
    这里要反其道而行。

    [x_{i+1}=ax_i+b ]

    解下方程发现其等比数列形式是:

    [x_{i+1}+frac{b}{a-1}=a(x_i+frac{b}{a-1}) ]

    那么$$x_n+frac{b}{a-1}=a^{n-1}(x_1+frac{b}{a-1})$$
    咦,(t)是指数!

    [a^{t-1}equivfrac{x_n+frac{b}{a-1}}{x_1+frac{b}{a-1}}pmod p ]

    其中(x_n=t)
    然后套上(BSGS)模板就可以了。

    显然(a=0,a=1)的时候需要特判。
    我在特判上栽了两次。。。

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define re register
    #define il inline
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=5e4,mod=45807;
    int T;
    int p,a,b,s,t,z,y;
    il int gi()
    {
      re int x=0,t=1;
      re char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    il ll ksm(re ll S,re ll n)
    {
      re ll T=S;S=1;
      while(n)
        {
          if(n&1) S=S*T%p;
          T=T*T%p;
          n>>=1;
        }
      return S;
    }
    struct Hash_table
    {
      struct Edge{int u,v,nxt;}e[N*10];
      int h[N],cnt;
      il void clear(){memset(h,-1,sizeof(h));cnt=0;}
      il void add(re int u,re int v,re int w){e[++cnt]=(Edge){w,v,h[u]};h[u]=cnt;}
      il int Query(re int x)
      {
        for(re int i=h[x%mod];i+1;i=e[i].nxt)
        if(e[i].u==x) return e[i].v;
        return -1;
      }
      il void solve(re int y,re int z)
      {
        y%=p;z%=p;
        if(!y||!z) {puts("-1");return;}
        re int m=sqrt(p)+1;clear();
        for(re int i=0,t=z;i<m;++i,t=1ll*t*y%p) add(t%mod,i,t);
        for(re int i=1,tt=ksm(y,m),t=tt;i<=m;++i,t=1ll*tt*t%p)
          {
        re int j=Query(t);if(j==-1) continue;
            printf("%d
    ",i*m-j+1);return;
          }
        puts("-1");
      }
    }BSGS;
    int main()
    {
      T=gi();
      while(T--)
        {
          p=gi();a=gi();b=gi();s=gi();t=gi();
          if(s==t) {puts("1");continue;}
          if(a==0)
        {
          if(b==t) puts("2");else puts("-1");//if(b==t) puts("1");????
          continue;
        }
          if(a==1)
        {
          if(b==0) puts("-1");
          else
            {
              re ll gu=1ll*(t+p-s)%p*ksm(b,p-2)%p;
              printf("%lld
    ",gu+1);//printf("%lld
    ",gu);????
            }
          continue;
        }
          re ll gu=1ll*b*ksm(a-1,p-2)%p;
          y=a;z=1ll*(t+gu)%p*ksm(s+gu,p-2)%p;
          BSGS.solve(y,z);
        }  
      return 0;
    }
    
  • 相关阅读:
    div 居中
    [转贴]Linux新增用户和组
    wmsys.WM_CONCAT
    [转]深刻理解Oracle数据库的启动和关闭
    [转]JAVA 程序中使用ORACLE 绑定变量( bind variable )
    考研的一些入门知识
    [转帖]什么是CPU的核心
    js空格处理函数
    [转]Vi 基础命令
    EMPTY_CLOB()/EMPTY_BLOB()使用
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9739821.html
Copyright © 2011-2022 走看看