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\n" );
144         else
145             printf( "no solution\n" );
146         return 0;
147     }
148     r = findroot(p);
149 //  fprintf( stderr, "%d\n", (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\n" );
153     else
154         printf( "%lld\n", ans );
155 }

时间: 2024-10-13 22:23:50

bzoj 3285 离散对数解指数方程的相关文章

[BZOJ 3751][NOIP2014]解方程(哈希)

Description 已知多项式方程: a0+a1*x+a2*x^2+...+an*x^n=0 求这个方程在[1,m]内的整数解(n和m均为正整数). Solution 一道很久很久以前就应该做的noip的题 一定要放上来是要见证我人品崩坏的一下午 生无可恋…QAQ 题解其实也很简单啦 随便找几个素数取模验证是不是等于0就好了 随便 随便 随便 随便找几个…素数 在WA\TLE\OLE间切换,最后还是抄了别人的几个素数 怀疑人生[望天 (BZOJ上的数据是加强了的,如果是ccf的数据那当然就随

BZOJ 3751 [NOIP2014]解方程

题解:运用筛法的思想,%p意义下,F(x)!=0则F(x+p)!=0 多选几个质数把F(x)!=0的筛去就可以了 #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m; int ans; int vis[1000009]; int p[51]={0,30011,11261,14843,19997,21893}; int a[200][51]; void Min

bzoj1644 / P1649 [USACO07OCT]障碍路线Obstacle Course

P1649 [USACO07OCT]障碍路线Obstacle Course bfs 直接上个bfs 注意luogu的题目和bzoj有不同(bzoj保证有解,还有输入格式不同). 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 #define pi pair<int,int> 7 #defin

BZOJ 3129 [Sdoi2013]方程 不定方程解的个数+组合数取模

题意:链接 方法:不定方程解的个数+组合数取模 解析: 先看n1与n2的部分的限制. 对于后半部分的限制来说,我们直接减去An1+i?1就可以转化一下求正整数解. 但是前半部分呢? 跟上一道猴子那个很像. 所以我们容斥搞就行了. 但是这道题好像不好写的地方不在这? 这题TMD不就是礼物吗! 大组合数取模如何取? 请参见我<BZOJ 礼物>的题解. 另外吐槽题干 明明是X1+X2+-+Xn=m 并不是小于等于 代码: #include <cstdio> #include <cs

A*算法详解 BZOJ 1085骑士精神

转载1:A*算法入门 http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx 在看下面这篇文章之前,先介绍几个理论知识,有助于理解A*算法. 启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标.这样可以省略大量无畏的搜索路径,提到了效率.在启发式搜索中,对位置的估价是十分重要的.采用了不同的估价可以有不同的效果. 估价函数:从当前节点移动到目标节点的预估费用:这个估计

BZOJ 3704(昊昊的机油之GRST-维护构造贪心解)

3704: 昊昊的机油之GRST Time Limit: 10 Sec  Memory Limit: 1024 MB Submit: 47  Solved: 15 [Submit][Status] Description 昊昊有个好机油,他就是传说中的着力点.现在昊昊获得了一份长度为n的GRST牌(mod 4 意义下),打算作为送给好机油的生日礼物(不是在2月的么).但是,昊昊深知他的机油是个神犇,作为数字控的他,只会喜欢特定的序列.但是昊昊不怕,他可以使用一次菲亚特(他的机油最喜欢的大招),将

BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]

3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1017  Solved: 466[Submit][Status][Discuss] Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列.但是小C有一个问题需要你的帮助:给定整数x,求所有可以生成出的,且满足数列中

BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]

http://www.lydsy.com/JudgeOnline/problem.php?id=2199 题意:裸的2-SAT,但是问每个变量在所有解中是只能为真还是只能为假还是既可以为真又可以为假 这样的话求$SCC$的做法就不好做了 于是只能用$naive$做法了,枚举每个变量选择真假然后$dfs$一遍看看是否可行 #include <iostream> #include <cstdio> #include <cstring> #include <algori

BZOJ 3101(N皇后-N皇后O(n)构造一组解的方法)

3101: N皇后 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special Judge Submit: 70  Solved: 32 [Submit][Status] Description n*n的棋盘,在上面摆下n个皇后,使其两两间不能相互攻击- Input 一个数n Output 第i行表示在第i行第几列放置皇后 Sample Input 4 Sample Output 2 4 1 3 HINT 100%的数据3<n<1000000.输出