\[ 求解x^{2^{30}+3}=c\pmod n \]ios
其中\(n=p\cdot q\),\(p\)爲小於\(x\)的最大素數,\(q\)爲大於\(x\)的最小素數,\(x\)爲\([10^5,10^9]\)內隨機選擇的數。\(0< c<n\)。c++
令\(a=2^{30}+3\),因此有\(x^a=c\pmod n\Leftrightarrow x^{a\ mod \ \varphi(n)}=c\pmod n\)。又由於\(n=p\cdot q\),因此有\(x^{a\ mod \ (p-1)\cdot (q-1)}=c\pmod n\),求出\(a\)在模\((p-1)\cdot (q-1)\)意義下的逆元\(d\),則\(x=c^d\pmod n\)。而後用中國剩餘定理求解答案\(x\)便可。spa
至於\(p,q\),由題意可知,\(p,q\)都在\(\sqrt{n}\)附近,因此暴力求解便可。code
#include<bits/stdc++.h> using namespace std; #define int long long int exgcd(int a,int b,int &x,int &y){ //擴展歐幾里得 if(a==0&&b==0) return -1; if(b==0){ x=1;y=0; return a; } int gcd=exgcd(b,a%b,y,x); y-=a/b*x; return gcd; } int solve(int a,int b,int c){ //求逆元 int x,y; int gcd=exgcd(a,b,x,y); if(c%gcd!=0) return -1; return (x%b+b)%b; } int fpow(int a,int b,int mod){ //快速冪 int ans=1;a%=mod; while(b){ if(b&1) (ans*=a)%=mod; (a*=a)%=mod; b>>=1; } return ans; } int fmul(int a,int b,int mod){ //快速乘 int ans=0;a%=mod; while(b){ if(b&1) ans=(ans+a)%mod; a=(a+a)%mod; b>>=1; } return ans; } int crt(int ai[], int mi[], int len) { //中國剩餘定理 int ans = 0, lcm = 1; for (int i = 0; i < len; i++) lcm *= mi[i]; for (int i = 0; i < len; i++) { int Mi = lcm / mi[i]; int inv = fpow(Mi, mi[i] - 2, mi[i]); int x = fmul(fmul(inv, Mi, lcm), ai[i], lcm); //若lcm大於1e9須要用快速乘fmul ans = (ans + x) % lcm; } return ans; } int mi[5],ai[5]; signed main(){ ios::sync_with_stdio(false); cin.tie(0); int T,ca=0;cin>>T; while(T--){ cout<<"Case "<<++ca<<": "; int n,c,p,q;cin>>n>>c; for(int i=sqrt(n);i>=0;i--) if(n%i==0){ p=i;q=n/i; break; } int d=solve((1LL<<30)+3,(p-1)*(q-1),1); if(d==-1){ cout<<"-1"<<endl; continue; } ai[0]=fpow(c,d,p);ai[1]=fpow(c,d,q); mi[0]=p;mi[1]=q; cout<<crt(ai,mi,2)<<endl; } return 0; }