【BZOJ1467/2480】Pku3243 clever Y/Spoj3105 Mod EXBSGS
阿新 • • 發佈:2017-07-30
sof i++ long mod data -s for scrip input
2 4 3
0 0 0
No Solution
【BZOJ1467/2480】Pku3243 clever Y/Spoj3105 Mod
Description
已知數a,p,b,求滿足a^x≡b(mod p)的最小自然數x。Input
每個測試文件中最多包含100組測試數據。 每組數據中,每行包含3個正整數a,p,b。 當a=p=b=0時,表示測試數據讀入完全。Output
對於每組數據,輸出一行。 如果無解,輸出“No Solution”(不含引號),否則輸出最小自然數解。Sample Input
5 58 332 4 3
Sample Output
9No Solution
HINT
100%的數據,a,p,b≤1e9。
題解:EXBSGS
因為A和C不互質,所以我們令A,B,C同時除以gcd(A,C),得到的C‘可能與A還不互質,所以我們再除上gcd(A,C‘),直到A,C互質。
此時得到方程$A^{x-k}*{A^k\over g_1*g_2...g_k}=B‘(mod C‘)$
將${A^k\over g_1*g_2...g_k}$除過去,然後套用BSGS即可。
#include <cstdio> #include <cstring> #include <iostream> #include <map> #include <cmath> using namespace std; typedef long long ll; map<int,int> mp; int pm(int a,int b,int c) { int ret=1; while(b) { if(b&1) ret=(ll)ret*a%c; a=(ll)a*a%c,b>>=1; } return ret; } int gcd(int a,int b) { return b?gcd(b,a%b):a; } int BSGS(int a,int b,int c,int d) { int x,y,i; mp.clear(); int M=ceil(sqrt(c)); for(x=b,i=0;i<=M;i++,x=(ll)x*a%c) mp[x]=i; for(y=d,x=pm(a,M,c),i=1;i<=M;i++) { y=(ll)y*x%c; int tmp=mp[y]; if(tmp) return (ll)i*M-tmp; } return -1; } void work(int a,int b,int c) { int A=1,k=0; for(int i=0;(1<<i)<=c;i++) { if(pm(a,i,c)==b) { printf("%d\n",i); return ; } } while(1) { int g=gcd(a,c); if(g==1) break; if(b%g!=0) { printf("No Solution\n"); return ; } b/=g,c/=g,A=((ll)A*a/g)%c,k++; } int tmp=BSGS(a,b,c,A); if(tmp==-1) printf("No Solution\n"); else printf("%d\n",tmp+k); } int main() { int a,b,c; while(1) { scanf("%d%d%d",&a,&c,&b); if(!a&&!b&&!c) return 0; if(!a&&!b) printf("1\n"); else a%=c,b%=c,work(a,b,c); } }
【BZOJ1467/2480】Pku3243 clever Y/Spoj3105 Mod EXBSGS