zoukankan      html  css  js  c++  java
  • 【POJ2417】baby step giant step

      最近在学习数论,然而发现之前学的baby step giant step又忘了,于是去翻了翻以前的代码,又复习了一下。

      觉得总是忘记是因为没有彻底理解啊。

      

     

      注意baby step giant step只能用在b和p互质的情况下,因为只有b和p互质的情况下,b才有mod p下的逆元。(下面要用到逆元)

      当b和p不互质,就要处理一下。现在就正在做这么一题,方法以后再写。

     

      

     

      求a^(-m)就用到了求逆元了,那么如何求逆元呢?我学了两种方法:

      ·1:欧拉定理:当a和n互质,a^φ ( n) 1(mod n)。【φ ( n) 是小于等于n的与n互质的数的个数】

      ·2:拓展欧几里德:设a在mod n下的逆元是x,则满足:ax ≡ 1(mod n)

               即ax+ny=1。(a和n是常数,x和y是未知数,用拓展欧几里德求解即可)

     

      注:只有当a和n互质,a才有mod n下的逆元。

     

      代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 #define LL long long
     9 #define Maxn 1000010
    10 
    11 struct node
    12 {
    13     int idx;
    14     LL val;
    15 }baby[Maxn];
    16 
    17 bool cmp(node x,node y) {return x.val!=y.val ? x.val<y.val : x.idx<y.idx;}
    18 
    19 int binsearch(int cnt,LL tmp)
    20 {
    21     int head=0,tail=cnt;
    22     while(head<=tail)
    23     {
    24         int mid=(head+tail)>>1;
    25         if(baby[mid].val==tmp) return baby[mid].idx;
    26         if(baby[mid].val<tmp) head=mid+1;
    27         else tail=mid-1;
    28     }
    29     return -1;
    30 }
    31 
    32 LL powmod(LL a,LL b,LL mod)
    33 {
    34     LL ret=1;
    35     a%=mod;
    36     while(b)
    37     {
    38         if(b&1) ret=(ret*a)%mod;
    39         a=(a*a)%mod;    
    40         b>>=1;
    41     }
    42     return ret;
    43 }
    44 
    45 int main()
    46 {
    47     LL p,b,n;
    48     while(scanf("%lld%lld%lld",&p,&b,&n)!=EOF)
    49     {
    50         int m=(int)ceil(sqrt((double)(p-1))),cnt=0;
    51         baby[0].idx=0,baby[0].val=1;
    52         for(int i=1;i<m;i++)
    53          baby[i].idx=i,baby[i].val=(baby[i-1].val*b)%p;
    54         sort(baby,baby+m,cmp);
    55         for(int i=1;i<m;i++)
    56           if(baby[i].val!=baby[cnt].val) baby[++cnt]=baby[i];
    57         LL bm=powmod(powmod(b,p-2,p),m,p);
    58         //printf("bm = %lld
    ",bm);
    59         int ans=-1;
    60         LL tmp=n;
    61         for(int i=0;i<m;i++)
    62         {
    63             int pos=binsearch(cnt,tmp);
    64             if(pos!=-1)
    65             {
    66                 ans=i*m+pos;
    67                 break;
    68             }
    69             tmp=(tmp*bm)%p;
    70         }
    71         if(ans==-1) printf("no solution
    ");
    72         else printf("%d
    ",ans);
    73     }
    74     return 0;
    75 }
    poj2417

    2016-02-03 09:50:33

     

  • 相关阅读:
    EasyUI datagrid 的多条件查询
    js将时间戳转换为日期类型
    js限制字符串长度,超出的部分补...
    js打印WEB页面内容代码大全
    js倒计时一分钟
    java获取上个星期第一天和最后一天
    两个Html页面之间值得传递
    jS处理中英文时间格式化问题
    JS获取当月第一天和最后一天
    Java 计算两个日期相差月数、天数
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5179015.html
Copyright © 2011-2022 走看看