【bzoj2242】[SDOI2011]计算器 EXgcd+BSGS
生活随笔
收集整理的這篇文章主要介紹了
【bzoj2242】[SDOI2011]计算器 EXgcd+BSGS
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
你被要求設計一個計算器完成以下三項任務: 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)的最小非負整數。輸入
輸入包含多組數據。
第一行包含兩個正整數T,K分別表示數據組數和詢問類型(對于一個測試點內的所有數據,詢問類型相同)。 以下行每行包含三個正整數y,z,p,描述一個詢問。輸出
對于每個詢問,輸出一行答案。對于詢問類型2和3,如果不存在滿足條件的,則輸出“Orz, I cannot find x!”,注意逗號與“I”之間有一個空格。樣例輸入
【樣例輸入1】
3 1
2 1 3
2 2 3
2 3 3
【樣例輸入2】
3 2
2 1 3
2 2 3
2 3 3
樣例輸出
【樣例輸出1】
2
1
2
【樣例輸出2】
2
1
0
題解
EXgcd+BSGS
第一問直接快速冪。
第二問需要將xy≡z(mod p)轉化為xy+tp=z,進而用EXgcd求解。
第三問是裸的BSGS。
根據費馬小定理可知如果有解,答案一定小于p。
設m=√p(向上取整),再設x=km+b,其中k<m,b<m。
那么就有y^(km+b)≡z(mod p),即y^b≡z/y^km(mod p)。
于是我們可以將所有的y^b mod p加入到map中,然后枚舉k,求出z/y^km,看是否有相同的值在map中即可。
本題特判比較多,具體詳見代碼。
#include <cstdio> #include <cmath> #include <map> using namespace std; typedef long long ll; map<ll , ll> f; map<ll , ll>::iterator it; ll pow(ll x , ll y , ll mod) {ll ans = 1;while(y){if(y & 1) ans = ans * x % mod;x = x * x % mod , y >>= 1;}return ans; } ll gcd(ll a , ll b) {return b ? gcd(b , a % b) : a; } void exgcd(ll a , ll b , ll &x , ll &y) {if(!b){x = 1 , y = 0;return;}exgcd(b , a % b , x , y);ll t = x;x = y , y = t - a / b * y; } int main() {int T , k;scanf("%d%d" , &T , &k);while(T -- ){ll y , z , p;scanf("%lld%lld%lld" , &y , &z , &p);switch(k){case 1: printf("%lld\n" , pow(y , z , p)); break;case 2:{y %= p , z %= p; ll t = gcd(y , p) , x1 , x2;if(z % t != 0){printf("Orz, I cannot find x!\n");break;}y /= t , p /= t , z /= t , exgcd(y , p , x1 , x2) , x1 *= z;while(x1 < 0) x1 += p;while(x1 - p >= 0) x1 -= p;printf("%lld\n" , x1);break;}default:{y %= p , z %= p; if(!y){if(!z) printf("1\n");else printf("Orz, I cannot find x!\n");break;}ll m = (ll)ceil(sqrt(p)) , i , flag = 0 , t = 1 , temp;f.clear();for(i = 0 ; i < m ; i ++ ){if(f.find(t) == f.end()) f[t] = i;t = t * y % p;}temp = pow(y , p - m - 1 , p) , t = 1;for(i = 0 ; i <= m ; i ++ ){it = f.find(z * t % p) , t = t * temp % p;if(it != f.end()){printf("%lld\n" , i * m + it->second) , flag = 1;break;}}if(!flag) printf("Orz, I cannot find x!\n");}}}return 0; }?
?
轉載于:https://www.cnblogs.com/GXZlegend/p/6999367.html
總結
以上是生活随笔為你收集整理的【bzoj2242】[SDOI2011]计算器 EXgcd+BSGS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 瑞芯微芯片怎么样 AI芯片仅次于海思
- 下一篇: Visual Studio 中指定自定义