zoukankan      html  css  js  c++  java
  • 【算法乱讲】BSGS

    Description
    Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that BL== N (mod P)
    Input
    Read several lines of input, each containing P,B,N separated by a space.
    Output
    For each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print "no solution".
    Sample Input
    5 2 1
    5 2 2
    5 2 3
    5 2 4
    5 3 1
    5 3 2
    5 3 3
    5 3 4
    5 4 1
    5 4 2
    5 4 3
    5 4 4
    12345701 2 1111111
    1111111121 65537 1111111111
    
    Sample Output
    0
    1
    3
    2
    0
    3
    1
    2
    0
    no solution
    no solution
    1
    9584351
    462803587



    显然,这是一道bsgs的裸题
    那么bsgs是什么玩意呢,
    我们先玩一玩式子
    令 m=ceil(sqrt(p))设a^(m*i+j)=b(mod p)

    显然 a^j*a^(m*i)=b(mod p) 
      a^j=b*a^(-m*i) (mod p)

    因此,我们预处理所有可能的a^j丢进哈希表中然后我们枚举i,
    看看有没有可能对应的j
    所以我们的算法时间复杂度为O(n^0.5)
     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<iostream>
     4 #include<string>
     5 #include<string.h>
     6 #include<algorithm>
     7 #include<math.h>
     8 #include<queue>
     9 #include<map>
    10 #include<vector>
    11 #include<set>
    12 #define il inline
    13 #define re register
    14 using namespace std;
    15 typedef long long ll;
    16 struct hash_set{
    17     ll v[111111];
    18     int next[111111],g[111111],w[111111],tot;
    19     il void clear(){
    20         memset(g,false,sizeof(g));tot=0;
    21     }
    22     il void insert(ll h,int f){
    23         v[++tot]=h;
    24         w[tot]=f;
    25         next[tot]=g[h%100007];
    26         g[h%100007]=tot;
    27     }
    28     il int find(ll h){
    29         for(re int i=g[h%100007];i;i=next[i])
    30             if(h==v[i]) return w[i];
    31         return -1;
    32     }
    33 } p;
    34 ll A,B,P,m,t,s;
    35 il ll ksm(re ll base,re ll pow){
    36     if(pow<0){
    37         cout<<"-1";exit(0);
    38     }
    39     ll ans=1;
    40     for(;pow;pow>>=1){
    41         if(pow&1) ans=ans*base%P;
    42         base=base*base%P; 
    43     }
    44     return ans;
    45 }
    46 il ll rev(re ll a){
    47     return ksm(a,P-2);
    48 }
    49 il void init(){
    50     p.clear();
    51     m=ceil(sqrt(P));t=1;
    52     for(int i=0;i<m;i++){
    53         if(p.find(t)<0) p.insert(t,i);
    54         t=t*A%P;
    55     }
    56     //cout<<endl;
    57     for(int i=0,l;i<=P/m;i++){
    58         t=rev(ksm(A,m*i));
    59     //    cout<<t<<" "<<m*i<<" ";
    60         s=t*B%P;
    61     //    cout<<s<<endl;
    62         l=p.find(s);
    63         if(l>=0){
    64             printf("%lld
    ",m*i+l);
    65             return;
    66         }
    67     }
    68     printf("no solution
    ");
    69 }
    70 int main(){
    71     while(scanf("%lld%lld%lld",&P,&A,&B)!=EOF){
    72         init();
    73     }
    74     return 0;
    75 }
    
    
  • 相关阅读:
    WampServer Mysql配置
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 前10名
  • 原文地址:https://www.cnblogs.com/ExiledPoet/p/5836006.html
Copyright © 2011-2022 走看看