• bzoj 3285 离散对数解指数方程


      1 /**************************************************************
      2     Problem: 3285
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:756 ms
      7     Memory:32072 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cmath>
     12 #include <cstring>
     13 #include <cctype>
     14 #define N 1000010
     15  
     16 typedef long long dnt;
     17  
     18 const int Hmod = 60793;
     19 struct Hash {
     20     int head[N], key[N], val[N], next[N], etot;
     21     void init() {
     22         etot = 0;
     23         memset( head, 0, sizeof(head) );
     24     }
     25     void insert( int k, int v ) {
     26         int kk = k%Hmod;
     27         etot++;
     28         key[etot] = k;
     29         val[etot] = v;
     30         next[etot] = head[kk];
     31         head[kk] = etot;
     32     }
     33     int query( int k ) {
     34         int kk = k%Hmod;
     35         for( int t=head[kk]; t; t=next[t] )
     36             if( key[t]==k ) return val[t];
     37         return -1;
     38     }
     39 }hash;
     40  
     41 dnt mpow( dnt a, int b, int c ) {
     42     dnt rt;
     43     for( rt=1; b; b>>=1,a=(a*a)%c )
     44         if( b&1 ) rt=(rt*a)%c;
     45     return rt;
     46 }
     47 int findroot( int p ) {
     48     int phi = p-1;
     49     int tmp = phi;
     50     int stk[50], top;
     51     top = 0;
     52     for( int i=2; i<=(1<<16); i++ ) {
     53         if( tmp%i==0 ) {
     54             stk[++top] = i;
     55             do {
     56                 tmp/=i;
     57             }while( tmp%i==0 );
     58         }
     59     }
     60     if( tmp!=1 ) 
     61         stk[++top] = tmp;
     62     for( int r=1; ; r++ ) {
     63         bool ok = true;
     64         for( int i=1; i<=top; i++ ) {
     65             if( mpow(r,phi/stk[i],p)==1 ) {
     66                 ok=false;
     67                 break;
     68             }
     69         }
     70         if( ok ) return r;
     71     }
     72 }
     73 dnt ind( dnt r, int a, int p ) {    //  ind_r(a) mod p-1
     74     int m = ceil(sqrt(p-1));
     75     hash.init();
     76     dnt cur = 1;
     77     for( int i=0; i<m; i++ ) {
     78         if( cur==a ) return i;
     79         hash.insert( cur, i );
     80         cur = (cur*r) % p;
     81     }
     82     dnt base;
     83     base = cur = mpow(cur,p-2,p);
     84     for( int i=m; i<p; i+=m,cur=(cur*base)%p ) {
     85         int j = hash.query( a*cur%p );
     86         if( j!=-1 ) return i+j;
     87     }
     88     return -1;  //  impossible
     89 }
     90 dnt gcd( dnt a, dnt b ) {
     91     return b ? gcd(b,a%b) : a;
     92 }
     93 void exgcd( dnt a, dnt b, dnt &d, dnt &x, dnt &y ) {
     94     if( b==0 ) {
     95         d=a, x=1, y=0;
     96     } else {
     97         exgcd(b,a%b,d,y,x);
     98         y-=a/b*x;
     99     }
    100 }
    101 dnt meq( dnt a, dnt b, dnt c ) {    //  ax=b mod c
    102     dnt d, dd, x, y;
    103     a = (a%c+c)%c;
    104     b = (b%c+c)%c;
    105     d = gcd(a,c);
    106     if( b%d!=0 ) return -1;
    107     exgcd(a/d,c/d,dd,x,y);
    108     x = x*(b/d);
    109     x = (x%(c/d)+(c/d))%(c/d);
    110     if( x==0 ) x+=c/d;
    111     return x;
    112 }
    113  
    114 dnt a, b, c, g, p, r;
    115 int aa[N], bb[N], cc[N], gg[N];
    116  
    117 void read( int a[] ) {
    118     int i;
    119     char ch;
    120     for( i=0; isdigit(ch=getchar()); i++ )
    121         a[i] = ch-'0';
    122     a[i] = -1;
    123 }
    124 dnt modulo( int a[], dnt mod ) {
    125     dnt rt = 0;
    126     for( int i=0; a[i]!=-1; i++ )
    127         rt = (rt*10 + a[i]) % mod;
    128     return rt;
    129 }
    130 int main() {
    131     read(aa); 
    132     read(bb); 
    133     read(cc); 
    134     read(gg);
    135     scanf( "%lld", &p );
    136     a = modulo(aa,p-1); 
    137     b = modulo(bb,p-1),
    138     c = modulo(cc,p); 
    139     g = modulo(gg,p);
    140  
    141     if( g%p==0 || c%p==0 ) {
    142         if( g%p==0 && c%p==0 ) 
    143             printf( "1
    " );
    144         else
    145             printf( "no solution
    " );
    146         return 0;
    147     }
    148     r = findroot(p);
    149 //  fprintf( stderr, "%d
    ", (int)r );
    150     dnt ans = meq( a*ind(r,g,p), ind(r,c,p)-b*ind(r,g,p), p-1 );
    151     if( ans<0 ) 
    152         printf( "no solution
    " );
    153     else
    154         printf( "%lld
    ", ans );
    155 }
    View Code
  • 相关阅读:
    HDU 4081 Qin Shi Huang's National Road System
    POJ 2075 Tangled in Cables 最小生成树
    HDU 2487 Ugly window
    UVA 11426 GCD Extrme (Ⅲ)
    POJ_1220_Nmber Sequence
    Fibonacci数列对任何数取模都是一个周期数列
    POJ_3321_APPLE_TREE
    webpack配置---设置快捷打包和浏览器自动刷新
    sublime中css输入分号后自动提示的烦恼
    MongoDB的基本使用
  • 原文地址:https://www.cnblogs.com/idy002/p/4567464.html
Copyright © 2020-2023  润新知