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

    3122: [Sdoi2013]随机数生成器

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 1442  Solved: 552

    Description

    Input

    输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数。  

    接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据。保证X1和t都是合法的页码。 

    注意:P一定为质数

    Output

    共T行,每行一个整数表示他最早读到第t页是哪一天。如果他永远不会读到第t页,输出-1。 

    Sample Input

    3
    7 1 1 3 3
    7 2 2 2 0
    7 2 2 2 1


    Sample Output


    1
    3
    -1

    HINT

    0<=a<=P-1,0<=b<=P-1,2<=P<=10^9

    【分析】

      这题简直坑爹到家了!!p是质数不说,还有各种恶心特判!!!!

      a=0,a=1,b=0都要特判。

      虽说自己推出了通项公式,但是哪里的除法可以逆元哪里不可以都不知道,一开始通分各种wa!!

      看别人的题解吧:

    已知xn=a*xn-1+b%p,求最小的n令xn=t

    首先,若x1=t,则返回1

             若a=0,则若b=t 返回2,否则无解

             若a=1,则T=t-x1+p%p,可以列出方程

             b*x+p*y==T % p

             若a>=2,则根据等比数列和可得

             xn=t=x1*a^(n-1)+b*(a^(n-1)-1)/(a-1) %p

             由于p为质数,所以令c=inv[a-1]=(a-1)^(p-2)

             x1*a^(n-1)+b*c*(a^(n-1))==b*c+t %p

             (x1+b*c)*(a^(n-1))==b*c+t % p

             令A=x1+b*c,B=p,C=b*c+t

             则就是解A*X+B*Y==C %p

             解出来X=a^(n-1),然后这个用BSGS求就可以了

    http://www.cnblogs.com/qzqzgfy/p/5581955.html

    我的代码:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<cmath>
      8 using namespace std;
      9 #define LL long long
     10 #define Maxn 35000
     11 
     12 struct node
     13 {
     14     LL id,val;
     15 }t[Maxn];
     16 
     17 LL ax,ay;
     18 LL exgcd(LL a,LL b)
     19 {
     20     if(b==0) {ax=1;ay=0;return a;}
     21     LL g=exgcd(b,a%b);
     22     LL xx=ax;
     23     ax=ay;ay=xx-(a/b)*ay;
     24     return g;
     25 }
     26 
     27 bool cmp(node x,node y) {return (x.val==y.val)?(x.id<y.id):(x.val<y.val);}
     28 
     29 LL cnt;
     30 
     31 LL t_div(LL x)
     32 {
     33     LL l=0,r=cnt;
     34     while(l<r)
     35     {
     36         LL mid=(l+r)>>1;
     37         if(t[mid].val==x) return t[mid].id;
     38         if(t[mid].val>x) r=mid-1;
     39         else l=mid+1;
     40     }
     41     if(t[l].val==x) return t[l].id;
     42     return -1;
     43 }
     44 
     45 LL get_ans(LL k,LL a,LL c,LL p)
     46 {
     47     LL sq=(LL)ceil(sqrt((double)p));
     48     t[0].id=0;t[0].val=k%p;
     49     for(LL i=1;i<=sq;i++) t[i].val=(t[i-1].val*a)%p,t[i].id=i;
     50     
     51     sort(t+1,t+1+sq,cmp);
     52     cnt=0;
     53     for(LL i=1;i<=sq;i++) if(t[i].val!=t[i-1].val) t[++cnt]=t[i];
     54     
     55     LL bm=1;
     56     for(LL i=1;i<=sq;i++) bm=(bm*a)%p;
     57     LL g=exgcd(bm,p);
     58     ax=(ax%(p/g)+(p/g))%(p/g);
     59     bm=ax;
     60     
     61     LL tmp=c%p;
     62     for(LL i=0;i<=sq;i++)
     63     {
     64         LL now=t_div(tmp);
     65         if(now!=-1) return now+i*sq;
     66         tmp=(tmp*bm)%p;
     67     }
     68     return -1;
     69 }
     70 
     71 LL ffind(LL k,LL a,LL c,LL p)
     72 {
     73     LL x=k;
     74     for(LL i=0;i<=100;i++)
     75     {
     76         if(x==c) return i;
     77         x=(x*a)%p;
     78     }
     79     LL g;
     80     x=0;
     81     while((g=exgcd(a,p))!=1)
     82     {
     83         p/=g;
     84         k=(k*(a/g))%p;
     85         if(c%g!=0) return -1;
     86         c/=g;
     87         x++;
     88     }
     89     LL ans=get_ans(k,a,c,p);
     90     if(ans==-1) return -1;
     91     return ans+x;
     92 }
     93 
     94 int main()
     95 {
     96     int T,kase=0;
     97     scanf("%d",&T);
     98     while(T--)
     99     {
    100         // printf("%d: ",++kase);
    101         LL p,a,b,x,t,c;
    102         scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x,&t);
    103         // if(b==0) {printf("1
    ");continue;}
    104         if(t==x) {printf("1
    ");continue;}
    105         if(a==0&&b==t) {printf("2
    ");continue;}
    106         else if(a==0) {printf("-1
    ");continue;}
    107         if(a==1)
    108         {
    109             LL g=exgcd(b,p);
    110             c=t-x;c=(c%p+p)%p;
    111             if(c%g!=0) {printf("-1
    ");continue;}
    112             ax*=c/g;
    113             ax=(ax%(p/g)+(p/g))%(p/g);
    114             printf("%d
    ",ax+1);
    115             continue;
    116         }
    117         
    118         LL phi;
    119         if(b%(a-1)==0) phi=b/(a-1);
    120         else
    121         {
    122             if(exgcd(a-1,p)!=1) {printf("-1
    ");continue;}
    123             ax=(ax%p+p)%p;
    124             phi=(b*ax)%p;
    125         }
    126         LL A=x+phi,B=phi+t;
    127         
    128         if(b==0) A=x,B=t;
    129         
    130         A=(A%p+p)%p; B=(B%p+p)%p;
    131         // if(A==0) {printf("-1
    ");continue;}
    132         
    133         LL ans=ffind(A,a,B,p);
    134         
    135         if(ans==-1) printf("-1
    ");
    136         else printf("%lld
    ",ans+1);
    137     }
    138     return 0;
    139 }
    BZOJ 3211

    2016-09-05 18:24:44

  • 相关阅读:
    C++ 三数之和
    C++ 保存读取二进制
    流媒体 Ubuntu部署srs、windows部署nginx
    sql函数(三)MERGE INTO函数
    sql函数(二)LISTAGG()函数(列转行函数)
    sql函数(一)ROW_NUMBER() OVER()--表内分组并排序
    java注释(类、构造函数、方法、代码块、单行、属性注释)
    springBoot注解整理
    @DateTimeFormat与@JsonFormat作用
    DataJPA简述与注解
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5843227.html
Copyright © 2011-2022 走看看