数论 $2$ 合 $1$
$K=1$ 快速幂,$K=2$ $exgcd$ , $K=3$ $exBSGS$
都是板子就没什么好讲了...
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<map> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline int ksm(int x,int y,int mo) { int res=1; while(y) { if(y&1) res=1ll*res*x%mo; x=1ll*x*x%mo; y>>=1; } return res; } int gcd(int a,int b) { return b ? gcd(b,a%b) : a; } int exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0; return a; } int d=exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*y; return d; } map <int,int> mp; void exBSGS(int X,int Z,int mo) { if(Z==1) { printf("0 "); return; } int d=gcd(X,mo),t=0,k=1; while(d!=1) { if(Z%d) { printf("Orz, I cannot find x! "); return; } t++; Z/=d; mo/=d; k=1ll*k*(X/d)%mo; if(k==Z) { printf("%d ",t); return; } d=gcd(X,mo); } int m=sqrt(mo)+1; mp.clear(); for(int b=0,s=Z; b<m; b++,s=1ll*s*X%mo) mp[s]=b; for(int a=1,p=ksm(X,m,mo),s=1ll*k*p%mo; a<=m+1; a++,s=1ll*s*p%mo) { if(mp.find(s)==mp.end()) continue; printf("%d ",a*m-mp[s]+t); return; } printf("Orz, I cannot find x! "); } int T,K; int main() { T=read(),K=read(); int X,Z,mo; while(T--) { X=read(),Z=read(),mo=read(); if(K==1) { printf("%d ",ksm(X,Z,mo)); continue; } if(K==3) { exBSGS(X,Z,mo); continue; } int A=X,B=mo,x,y,d=exgcd(A,B,x,y); if(Z%d) { printf("Orz, I cannot find x! "); continue; } int t=B/d,ans=(1ll*x*(Z/d)%t+t)%t; printf("%d ",ans); } return 0; }