题目:
https://www.luogu.org/problemnew/show/P2485
题目简介:
你被要求设计一个计算器完成以下三项任务:
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。
为了拿到奖品,全力以赴吧!
题解:
问题一: 二分快速幂
1 ll Make(ll x,ll y,ll mod){ 2 if(y==0) return 1%mod; 3 ll mid=y/2; 4 ll ans=Make(x,mid,mod); 5 ans=(ans*ans)%mod; 6 if(y&1){ans=(ans*x)%mod;} 7 return ans; 8 } 9 void Next1(){ 10 Read(Y),Read(Z),Read(P); 11 ll ans=Make(Y,Z,P); 12 Write(ans); 13 return ; 14 }
问题二: 扩展欧几里得模板
1 ll ExGcd(ll a,ll b,ll &x,ll &y){ 2 if(b==0) { 3 x=1; 4 y=0; 5 return a; 6 } 7 ll res=ExGcd(b,a%b,y,x); 8 y-=a/b*x; 9 return res; 10 } 11 void Next2(){ 12 Read(Y),Read(Z),Read(P); 13 ll x,y,res; 14 if(Y==0 && Z!=0){ 15 printf("Orz, I cannot find x!\n"); 16 return ; 17 } 18 res=ExGcd(Y,P,x,y); 19 if(Z%res){ 20 printf("Orz, I cannot find x!\n"); 21 return ; 22 } 23 x=((Z/res*x%P)+P)%(P/res); 24 Write(x); 25 return ; 26 }
问题三:BabyStepGiantStep 【BSGS】
对于幂取模,直接硬来(枚举指数)时间复杂度是过不去的
分析:
对于 y^x ≡ z (mod p)
根据抽屉原理: y^(p+k) mod p 的值一定存在于 y^(1~p) mod p 中(因为mod p最多有p个值)
所以我们的考虑范围也就从 inf 缩小到了 p