bzoj2242(高次同余方程,线性同余方程)
#include<cstdio> #include<map> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; ll power(ll a,ll b,ll mod){ ll ans=1%mod; for (;b;b>>=1){ if(b&1) ans=ans*a%mod; a=a*a%mod; } return ans%mod; } ll exgcd(ll a,ll b,ll &x,ll &y){ if(b==0){ x=1; y=0; return a; } ll d=exgcd(b,a%b,x,y); ll z=x; x=y; y=z-(a/b)*y; return d; } ll babe(ll a,ll b,ll p){ map<int,int>hashl; hashl.clear(); b%=p; ll t=(int)sqrt(p)+1; for (int j=0;j<t;j++){ ll val=b*power(a,j,p)%p; hashl[val]=j; } a=power(a,t,p); if(a==0) return b==0?1:-1; for (int i=0;i<=t;i++){ ll val=power(a,i,p); ll j; if(hashl.find(val)==hashl.end()) j=-1; else j=hashl[val]; if(j>=0&&i*t-j>=0) return i*t-j; } return -1; } int main(){ int t,k; scanf("%d%d",&t,&k); ll y,z,p,x; if(k==1){ for (int i=1;i<=t;i++) { scanf("%lld%lld%lld",&y,&z,&p); printf("%lld\n",power(y,z,p)); } } if(k==2){ ll a,b; for (int i=1;i<=t;i++){ scanf("%lld%lld%lld",&a,&b,&p); int d=exgcd(a,p,x,y); if(b%d) printf("Orz, I cannot find x!\n"); else { ll s=p/d; x=(b/d*x%s+s)%s;//怎样找最小解 printf("%lld\n",x); } } } if(k==3){ ll a,b; for (int i=1;i<=t;i++){ scanf("%lld%lld%lld",&a,&b,&p); int h=babe(a,b,p); if(h==-1) printf("Orz, I cannot find x!\n"); else printf("%lld\n",h%p);记得mod p } } return 0; }