你被要求设计一个计算器完成以下三项任务:
1、给定y,z,p,计算Y^Z Mod P 的值;
2、给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数;
3、给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数。
标签:数据规模 输入 zoj problem log getchar std break esc
输入包含多组数据。
1 /************* 2 bzoj 2242 3 by chty 4 2016.11.9 5 *************/ 6 #include<iostream> 7 #include<cstdio> 8 #include<cstdlib> 9 #include<cstring> 10 #include<ctime> 11 #include<cmath> 12 #include<algorithm> 13 using namespace std; 14 #define FILE "read" 15 #define MAXN 99991 16 typedef long long ll; 17 struct node{ll v,f,num;}hash[MAXN+10]; 18 ll a,b,mod; 19 inline ll read() 20 { 21 ll x=0,f=1; char ch=getchar(); 22 while(!isdigit(ch)) {if(ch==‘-‘) f=-1; ch=getchar();} 23 while(isdigit(ch)) {x=x*10+ch-‘0‘; ch=getchar();} 24 return x*f; 25 } 26 void insert(ll v,ll x) 27 { 28 ll temp=v%MAXN; 29 while(hash[temp].f&&hash[temp].v!=v) {temp++; if(temp>MAXN) temp-=MAXN;} 30 if(!hash[temp].f) hash[temp].f=1,hash[temp].v=v,hash[temp].num=x; 31 } 32 ll find(ll v) 33 { 34 ll temp=v%MAXN; 35 while(hash[temp].f&&hash[temp].v!=v) {temp++; if(temp>MAXN) temp-=MAXN;} 36 if(!hash[temp].f) return -1; 37 else return hash[temp].num; 38 } 39 ll gcd(ll a,ll b) {return !b?a:gcd(b,a%b);} 40 ll exgcd(ll a,ll b,ll &x,ll &y) 41 { 42 if(!b) {x=1; y=0; return a;} 43 ll g=exgcd(b,a%b,x,y); 44 ll t=x;x=y;y=t-a/b*y; 45 return g; 46 } 47 void solve1(){ll sum=1;for(;b;b>>=1,a=a*a%mod)if(b&1)sum=sum*a%mod;printf("%d\n",sum);} 48 void solve2() 49 { 50 ll x,y,d=exgcd(a,mod,x,y); 51 if(b%d) {printf("Orz, I cannot find x!\n");return;} 52 ll t=mod/d; 53 while(x<0) x+=t; 54 while(x>=t) x-=t; 55 printf("%lld\n",x*b%mod); 56 } 57 void solve3() 58 { 59 if(mod==1) {puts("0"); return;} 60 a%=mod;b%=mod; 61 ll ret(1); 62 for(ll i=0;i<=50;i++) {if(ret==b) {printf("%lld\n",i); return; ret=ret*a%mod;}} 63 ll temp,ans(1),cnt(0); 64 while((temp=gcd(a,mod))!=1) 65 { 66 if(b%temp) {printf("Orz, I cannot find x!\n");return;} 67 mod/=temp; b/=temp; 68 ans=ans*(a/temp)%mod; 69 cnt++; 70 } 71 ll m=(ll)sqrt(mod*1.0),t(1); 72 for(ll i=0;i<m;i++) {insert(t,i);t=t*a%mod;} 73 for(ll i=0;i<m;i++) 74 { 75 ll x,y; 76 exgcd(ans,mod,x,y); 77 ll val=x*b%mod; 78 val=(val+mod)%mod; 79 ll j=find(val); 80 if(j!=-1) {printf("%lld\n",i*m+j+cnt);return;} 81 ans=ans*t%mod; 82 } 83 printf("Orz, I cannot find x!\n"); 84 return; 85 } 86 void pre() {for(ll i=0;i<=MAXN;i++)hash[i].f=0,hash[i].num=hash[i].v=-1;} 87 int main() 88 { 89 freopen(FILE".in","r",stdin); 90 freopen(FILE".out","w",stdout); 91 ll T=read(),flag=read(); 92 while(T--) 93 { 94 pre(); 95 a=read(); b=read(); mod=read(); 96 switch(flag) 97 { 98 case 1:solve1();break; 99 case 2:solve2();break; 100 case 3:solve3();break; 101 } 102 } 103 return 0; 104 }
标签:数据规模 输入 zoj problem log getchar std break esc
原文地址:http://www.cnblogs.com/chty/p/6049531.html