题目描述
你被要求设计一个计算器完成以下三项任务:
1、给定y、z、p,计算y^z mod p 的值;
2、给定y、z、p,计算满足xy ≡z(mod p)的最小非负整数x;
3、给定y、z、p,计算满足y^x ≡z(mod p)的最小非负整数x。
为了拿到奖品,全力以赴吧!
输入输出格式
输入格式:
输入文件calc.in 包含多组数据。
第一行包含两个正整数T、K,分别表示数据组数和询问类型(对于一个测试点内的所有数
据,询问类型相同)。
以下T 行每行包含三个正整数y、z、p,描述一个询问。
输出格式:
输出文件calc.out 包括T 行.
对于每个询问,输出一行答案。
对于询问类型2 和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”。
输入输出样例
输入样例#1:
复制
3 1 2 1 3 2 2 3 2 3 3
输出样例#1: 复制
2 1 2
输入样例#2: 复制
3 2 2 1 3 2 2 3 2 3 3
输出样例#2: 复制
2 1 0
输入样例#3: 复制
4 3 2 1 3 2 2 3 2 3 3 2 4 3
输出样例#3: 复制
0 1 Orz, I cannot find x! 0
说明
设问题给的是 a ,b p;
k==1 谁都会吧 = =
k=2: 扩展欧几里得 设d=(a,p) ,若d !| b 无解,
当d=1; 套班子,在0到p-1上有一个解
当d!=1, 套板子,最后设 t = b/d,也即是b是gcd的几倍,然后由于x和y算出来是除了d的,所以最后x要乘t,在0到p/d-1上有一个解
k=3 出门左转,EXBSGS
1 #include"bits/stdc++.h" 2 using namespace std; 3 typedef long long ll; 4 5 ll work1(ll a,ll b,ll mod) 6 { 7 ll ans=1;ll base=a%mod; 8 while (b){if(b&1)ans=(ans*base)%mod;b>>=1;base=base*base%mod;}return ans; 9 } 10 11 void exgcd(ll &x,ll &y,ll a,ll b) 12 { 13 if(b==0){x=1,y=0;return ;} 14 exgcd(x,y,b,a%b);ll t=x; x=y;y=(t-(a/b)*y); 15 } 16 17 unordered_map <ll,ll> mp; 18 19 20 21 22 ll bsgs(ll a,ll b,ll p) 23 { 24 b%=p; 25 if(b==1)return 0; ll d; ll k=1; int cnt=0; 26 27 while ((d=__gcd(a,p))^1) 28 { 29 if(b%d)return -1; 30 b/=d; p/=d;cnt++; 31 k=1ll*k*(a/d)%p; 32 if(k==b)return cnt; 33 34 // cout<<k<<" "<<a<<" "<<b<<" "<<p<<endl; 35 } 36 37 38 39 int m=sqrt(p)+1; ll kt=1; 40 mp.clear(); 41 for (int i=0;i<m;i++) 42 { 43 mp[1LL*kt*b%p]=i; 44 kt=kt*a%p; 45 46 } 47 48 k=k*kt%p; 49 50 for (int i=1;i<=m;i++) 51 { 52 if(mp.find(k)!=mp.end()) return i*m-mp[k]+cnt; 53 k=k*kt%p; 54 } 55 56 return -1; 57 58 } 59 60 61 62 63 int main() 64 65 { 66 /* int x,y; 67 exgcd(x,y,3,10); 68 cout<<(x%10+10)%10;*/ 69 70 71 72 73 ll T,k; ll y,z,p; 74 cin>>T>>k; 75 76 while (T--) 77 { scanf("%lld%lld%lld",&y,&z,&p); 78 if(k==1) 79 { 80 printf("%lld\n",work1(y,z,p)); 81 } 82 else if(k==2) 83 { 84 ll Gcd=__gcd(y,p); if(z%Gcd!=0) 85 {puts("Orz, I cannot find x!");continue;} 86 ll x1,y1; ll t=z/Gcd; 87 exgcd(x1,y1,y,p); 88 p=p/Gcd; 89 // cout<<x1<<endl; 90 printf("%lld\n",1ll*((x1*z/Gcd)%p+p)%p); 91 } 92 else 93 { 94 ll ans=bsgs(y,z,p); 95 if(ans!=-1)printf("%lld\n",ans); 96 else puts("Orz, I cannot find x!"); 97 } 98 } 99 100 }
原文地址:https://www.cnblogs.com/zhangbuang/p/10404534.html
时间: 2024-09-28 23:36:00