日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

x^A=B(mod C)的解 (离散对数与原根)

發(fā)布時間:2024/4/11 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 x^A=B(mod C)的解 (离散对数与原根) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目:http://acm.hdu.edu.cn/showproblem.php?pid=3930


題意:給定同余式,求它在內(nèi)的所有解,其中總是素數(shù)。


分析:解本同余式的步驟如下

? ? ??

? ? (1)求模的一個原根

? ? (2)利用Baby Step Giant Step求出一個,使得,因為為素數(shù),所以有唯一解。

? ? (3)設(shè),這樣就有,其中,那么得到。

? ? (4)求出所有的,可以知道一共有個解,我們求出所有的,然后排個序即可。


代碼:

#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include <math.h> #include <bitset> #include <map>using namespace std; typedef long long LL;const int N = 1000005;/**以下為求原根部分 */ bitset<N> prime; int p[N],pri[N]; int k,cnt;void isprime() {prime.set();for(int i=2; i<N; i++){if(prime[i]){p[k++] = i;for(int j=i+i; j<N; j+=i)prime[j] = false;}} }void Divide(LL n) {cnt = 0;LL t = (LL)sqrt(1.0*n);for(int i=0; p[i]<=t; i++){if(n%p[i]==0){pri[cnt++] = p[i];while(n%p[i]==0) n /= p[i];}}if(n > 1)pri[cnt++] = n; }LL multi(LL a,LL b,LL m) {LL ans = 0;a %= m;while(b){if(b & 1){ans = (ans + a) % m;b--;}b >>= 1;a = (a + a) % m;}return ans; }LL quick_mod(LL a,LL b,LL m) {LL ans = 1;a %= m;while(b){if(b&1){ans = multi(ans,a,m);b--;}b >>= 1;a = multi(a,a,m);}return ans; }LL broot(LL p) {Divide(p-1);for(int g=2 ;; g++){bool flag = true;for(int i=0; i<cnt; i++){LL t = (p - 1) / pri[i];if(quick_mod(g,t,p) == 1){flag = false;break;}}if(flag) return g;} } /**以上為求原根部分 *//** 以下為Baby_Step */LL gcd(LL a,LL b) {return b ? gcd(b,a%b):a; }void extend_Euclid(LL a,LL b,LL &x,LL &y) {if(b == 0){x = 1;y = 0;return;}extend_Euclid(b,a%b,x,y);LL tmp = x;x = y;y = tmp - (a / b) * y; }LL Inv(LL a,LL p) {return quick_mod(a,p-2,p); }LL Baby_Step(LL A,LL B,LL C) {map<LL,int> mp;LL M = ceil(sqrt(1.0*C));LL t = Inv(quick_mod(A,M,C),C);LL ans = 1;for(int i=0; i<M; i++){if(!mp.count(ans))mp[ans] = i;ans = multi(ans,A,C);}for(int i=0; i<M; i++){if(mp.count(B))return i * M + mp[B];B = multi(B,t,C);}return -1; } /** 以上為Baby_Step */LL ans[1005];void Work(LL A,LL B,LL C) {LL root = broot(C);LL t1 = Baby_Step(root,B,C);LL t2 = C - 1;LL d = gcd(A,t2);if(t1 % d){puts("-1");return;}LL x,y;extend_Euclid(A,t2,x,y);t2 /= d;t1 /= d;ans[0] = (x * t1 % t2 + t2) % t2;for(int i=1; i<d; i++)ans[i] = ans[i-1] + t2;for(int i=0; i<d; i++)ans[i] = quick_mod(root,ans[i],C);sort(ans,ans+d);for(int i=0; i<d; i++)cout<<ans[i]<<endl; }int main() {int T = 1;LL A,B,C;isprime();while(cin>>A>>C>>B){printf("case%d:\n",T++);Work(A,B,C);}return 0; }


總結(jié)

以上是生活随笔為你收集整理的x^A=B(mod C)的解 (离散对数与原根)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。