容易发现如果我们求出p和q这题就差不多快变成一个sb题了。
于是我们就用Pollard Rho算法进行大数分解。
至于这个算法的原理,emmm
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cctype> #include<ctime> using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } long long e,n,c; inline double random(double from,double to){ return rand()*1.0/RAND_MAX*(to-from)+from; } inline long long mul(long long a,long long b,long long mod){ long long ans=0; while(b){ if(b&1) ans=(ans+a)%mod; a=(a+a)%mod; b>>=1; } return ans; } inline long long Pow(long long a,long long b,long long mod){ long long ans=1; while(b){ if(b&1) ans=mul(ans,a,mod); a=mul(a,a,mod); b>>=1; } return ans; } inline long long gcd(long long a,long long b){ return b==0?a:gcd(b,a%b); } long long getprime(long long ret,long long c){ long long x=random(1,n); long long y=x;int k=2,cnt=1; while(1){ x=(mul(x,x,n)+c)%n; long long d=gcd((x-y+n)%n,n); if(d>1&&d<n) return d; if(x==y) return n; if(++cnt==k){ k<<=1; y=x; } } } void exgcd(long long a,long long b,long long &x,long long &y){ if(b==0){ x=1;y=0; return; } exgcd(b,a%b,x,y); long long tmp=x;x=y;y=tmp-a/b*y; } int main(){ srand(time(NULL)); e=read(),n=read(),c=read(); long long p=n; while(p>=n) p=getprime(n,random(1,n)); long long q=n/p; long long r=(p-1)*(q-1); long long ano,d; exgcd(e,r,d,ano); d=(d+r)%r; printf("%lld %lld ",d,Pow(c,d,n)); return 0; }