标签:name long step oid style map 计算 sdoi exgcd
#include<cstdio> #include<cmath> #include<map> using namespace std; typedef long long ll; int T,K;ll mod; map<int,int>a; ll fpow(ll a,ll p){ ll res=1; for(;p;p>>=1,a=a*a%mod) if(p&1) res=res*a%mod; return res; } void exgcd(ll a,ll b,ll &d,ll &x,ll &y){ if(!b){d=a;x=1;y=0;return ;} exgcd(b,a%b,d,y,x); y-=x*(a/b); } ll gcd(ll a,ll b){ if(!b) return a; return gcd(b,a%b); } void CE(ll y,ll z){ ll a=y,b=-mod,d,x; d=gcd(a,b); if(z%d){printf("Orz, I cannot find x!\n");return ;} a/=d;b/=d;z/=d; exgcd(a,b,d,x,y); x*=z;x%=b; while(x<0) x+=b; printf("%lld\n",x); } void babystep_gaintstep(ll x,ll z){ ll k=1,y=z%mod;x%=mod; if(!x&&!z){puts("1");return ;} if(!x){printf("Orz, I cannot find x!\n");return ;} ll m=ceil(sqrt(mod-1)); ll ni=fpow(x,m);ni=fpow(ni,mod-2); a.clear(); a[1]=m+1; for(ll j=1;j<m;j++){ k=k*x%mod; if(!a[k]) a[k]=j; } for(ll i=0;i<m;i++){ ll u=a[y]; if(u){ if(u==m+1) printf("%lld\n",i*m); else printf("%lld\n",i*m+u); return ; } y=y*ni%mod; } printf("Orz, I cannot find x!\n"); } int main(){ scanf("%d%d",&T,&K); if(K==1){ for(int y,z,p;T--;){ scanf("%d%d%d",&y,&z,&p); mod=p; printf("%lld\n",fpow(y,z)); } } else if(K==2){ for(int y,z,p;T--;){ scanf("%d%d%d",&y,&z,&p); mod=p; CE(y,z); } } else{ for(int y,z,p;T--;){ scanf("%d%d%d",&y,&z,&p); mod=p; babystep_gaintstep(y,z); } } return 0; }
标签:name long step oid style map 计算 sdoi exgcd
原文地址:http://www.cnblogs.com/shenben/p/6429937.html