bzoj 2242 计算器
题目大意:
你被要求设计一个计算器完成以下三项任务:
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)$的最小非负整数。
思路:
第一问快速幂即可 第二问把两边同除以$y$ 求一下逆元即可
第三问BSGS 其实就是分块大暴力
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #define ll long long 12 #define inf 2139062143 13 #define MAXN 100100 14 #define mod 100007 15 using namespace std; 16 inline int read() 17 { 18 int x=0,f=1;char ch=getchar(); 19 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 20 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 21 return x*f; 22 } 23 int n,Type,y,z,MOD; 24 struct HashTable 25 { 26 int fst[MAXN],key2[MAXN],nxt[MAXN],tot; 27 ll key1[MAXN]; 28 inline void mem(){memset(fst,0,sizeof(fst));tot=0;} 29 void ins(ll k1, int k2) 30 { 31 int hsh=(int)k1%mod; 32 key1[++tot]=k1,key2[tot]=k2; 33 nxt[tot]=fst[hsh],fst[hsh]=tot; 34 } 35 int find(ll k1) 36 { 37 int hsh=(int)k1%mod; 38 for(int i=fst[hsh];i;i=nxt[i]) 39 if(key1[i]==k1) return key2[i]; 40 return -1; 41 } 42 }hsh; 43 ll q_pow(ll bas,ll t) 44 { 45 ll res=1; 46 for(;t;t>>=1,(bas*=bas)%=MOD) 47 if(t&1) (res*=bas)%=MOD; 48 return res; 49 } 50 void bsgs() 51 { 52 int ok=0;hsh.mem(); 53 if(!(y%MOD)) {puts("Orz, I cannot find x!");return ;} 54 ll m=ceil(sqrt(MOD)),a=1ll,res; 55 for(int i=0;i<=m;i++) 56 hsh.ins(a*z%MOD,i),(a*=y)%=MOD; 57 a=1ll,res=q_pow(y,m); 58 for(int i=1,t;i<=m;i++) 59 { 60 (a*=res)%=MOD,t=hsh.find(a); 61 if(t!=-1) 62 { 63 printf("%lld\n", (i*m%MOD-t)%MOD); 64 ok=1;return ; 65 } 66 } 67 if(!ok) puts("Orz, I cannot find x!"); 68 } 69 int main() 70 { 71 n=read(),Type=read(); 72 while(n--) 73 { 74 y=read(),z=read(),MOD=read(); 75 if(Type==1) printf("%lld\n",q_pow(y,z)); 76 else if(Type==2) 77 { 78 if(!(y%MOD)&&z%MOD) puts("Orz, I cannot find x!"); 79 else printf("%lld\n",(q_pow(y,MOD-2)*z)%MOD); 80 } 81 else bsgs(); 82 } 83 }