zoukankan      html  css  js  c++  java
  • HDU5478 原根求解

    看别人做的很简单我也不知道是怎么写出来的

    自己拿到这道题的想法就是模为素数,那必然有原根r ,将a看做r^a , b看做r^b
    那么只要求出幂a,b就能得到所求值a,b

    自己慢慢化简就会发现可以抵消n
    然后扩展欧几里得解决,一个个枚举所有模的情况。。。。

    中间利用了欧拉准则可以知道 对所有奇素数而言: a^((p-1)/2) = -1(mod p) 

    利用上述准则,这样就不用baby_step giant_step的办法了

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long LL;
      4 
      5 const int N = 200010;
      6 
      7 LL P , k1,b1 , k2;
      8 bitset<N> prime;
      9 int p[N],pri[N];
     10 int k,cnt;
     11 
     12 void isprime()
     13 {
     14     prime.set();
     15     for(int i=2; i<N; i++)
     16     {
     17         if(prime[i])
     18         {
     19             p[k++] = i;
     20             for(int j=i+i; j<N; j+=i)
     21                 prime[j] = false;
     22         }
     23     }
     24 }
     25 
     26 void Divide(int n)
     27 {
     28     cnt = 0;
     29     int t = (int)sqrt(1.0*n+0.5);
     30     for(int i=0; p[i]<=t; i++)
     31     {
     32         if(n%p[i]==0)
     33         {
     34             pri[cnt++] = p[i];
     35             while(n%p[i]==0) n /= p[i];
     36         }
     37     }
     38     if(n > 1)
     39         pri[cnt++] = n;
     40 }
     41 
     42 void gcd(LL a , LL b , LL &d , LL &x , LL &y)
     43 {
     44     if(!b){d=a;x=1;y=0;}
     45     else{gcd(b,a%b,d,y,x);y-=x*(a/b);}
     46 }
     47 
     48 LL inv(LL a , LL n)
     49 {
     50     LL d,x,y;
     51     gcd(a,n,d,x,y);
     52     return d==1?(x+n)%n:-1;
     53 }
     54 
     55 LL quick_mod(LL a,LL b,LL m)
     56 {
     57     LL ans = 1;
     58     a %= m;
     59     while(b)
     60     {
     61         if(b&1)
     62         {
     63             ans = ans * a % m;
     64             b--;
     65         }
     66         b >>= 1;
     67         a = a * a % m;
     68     }
     69     return ans;
     70 }
     71 
     72 LL pow_mod(LL a , LL p , LL n)
     73 {
     74     LL ret= 1;
     75     while(p){
     76         if(p&1) ret = ret*a%n;
     77         a = a*a%n;
     78         p>>=1;
     79     }
     80     return ret;
     81 }
     82 
     83 LL mul_mod(LL a , LL b , int n)
     84 {
     85     return a*b%n;
     86 }
     87 
     88 //int log_mod(int a , int b , int n)
     89 //{
     90 //    int m , v , e=1 , i;
     91 //    m = (int)sqrt(n+0.5);
     92 //    v = inv(pow_mod(a,m,n) , n);
     93 //    map<int,int>x;
     94 //    x.clear();
     95 //    x[1] = 0;
     96 //    for(i=1 ; i<m ; i++){
     97 //        e = mul_mod(e , a , n);
     98 //        if(!x.count(e)) x[e]=i;
     99 //    }
    100 //    for(i=0 ; i<m ; i++){
    101 //        if(x.count(b)) return i*m+x[b];
    102 //        b = mul_mod(b,v,n);
    103 //    }
    104 //    return -1;
    105 //}
    106 
    107 #define pii pair<int,int>
    108 pii ans[N];
    109 
    110 int main()
    111 {
    112    // freopen("a.in" , "r" , stdin);
    113     int cas = 0;
    114     isprime();
    115     //>>k1>>b1>>k2
    116     while(cin>>P>>k1>>b1>>k2)
    117     {
    118         printf("Case #%d:
    " , ++cas);
    119         int tot = 0;
    120         /*P==2另外处理*/
    121         if(P==1){
    122             printf("%d %d
    " , 0,0);
    123             continue;
    124         }
    125         if(P==2){
    126             printf("%d %d
    " , 1,1);
    127             continue;
    128         }
    129         Divide(P-1);
    130 
    131         for(int g=2; g<P; g++)
    132         {
    133             bool flag = true;
    134             for(int i=0; i<cnt; i++)
    135             {
    136                 int t = (P - 1) / pri[i];
    137                 if(quick_mod(g,t,P) == 1)
    138                 {
    139                     flag = false;
    140                     break;
    141                 }
    142             }
    143             if(flag)
    144             {
    145                 LL root = g;
    146                 LL val = (P-1)/2;
    147                // cout<<root<<" "<<val<<endl;
    148                 LL d,x,y;
    149                 gcd(b1+k1 , -1 , d , x , y);
    150                 x = x*val , y = y*val;
    151 
    152                 x = ((x%(P-1))+(P-1))%(P-1);
    153                 y = ((y%(P-1))+(P-1))%(P-1);
    154                 for(int i=0 ; i<P-1 ; i++){
    155 
    156                     if((x*k1-y*k2)%(P-1)==0){
    157                             LL a = pow_mod(root , x , P);
    158                         LL b = pow_mod(root , y , P);
    159                         if(a>0&&b>0) ans[tot++] = make_pair((int)a , (int)b);
    160                     }
    161                     x = (x+1)%(P-1);
    162                     y = (y+b1+k1)%(P-1);
    163                 }
    164                 break;
    165             }
    166         }
    167         sort(ans , ans+tot);
    168         tot = unique(ans , ans+tot)-ans;
    169         if(tot==0) puts("-1");
    170         else{
    171             for(int i=0 ; i<tot ; i++) printf("%d %d
    " , ans[i].first , ans[i].second);
    172         }
    173     }
    174     return 0;
    175 }
  • 相关阅读:
    登录 要求 密码必须包含数字、大写字母、小写字母、特殊字字符4种中至少3种
    job 异步获取
    g++的使用
    extern "c"
    C/C++定义全局变量/常量几种方法的区别
    使用Github管理cocos2dx版本
    二维码限制扫描区域
    Xcode路径改变之后,Cocopods不能使用,一行命令解决
    iOS之精确定时器
    iOS开发/App安全/代码自动混淆笔记
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4841420.html
Copyright © 2011-2022 走看看