BZOJ 2242: [SDOI2011]计算器
思路:BSGS+逆元
代码:
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<int,pii> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head map<int, int>mp; LL q_pow(LL n, LL k, LL p) { LL ans = 1; if(k == -1) return 0; while(k) { if(k&1) ans = (ans*n) % p; n = (n*n) % p; k >>= 1; } return ans; } int BSGS(int a, int b, int c) { if(a%c == 0 && b%c != 0 ) return -1; int m = ceil(sqrt(c)), base = 1; mp.clear(); for (int i = 0; i < m; i++) { if(mp.find(base) == mp.end()) mp[base] = i; base = (1LL * base * a) % c; } int D = 1; for (int i = 0; i < m; i++) { int x = (b * q_pow(D, c - 2, c)) % c; if(mp.find(x) != mp.end()) return i*m + mp[x]; D = (1LL * D * base) % c; } return -1; } int main() { int T, op, y, z, p; while( ~scanf("%d %d", &T, &op)) { for (int i = 1; i <= T; i++) { scanf("%d %d %d", &y, &z, &p); if(op == 1) { printf("%lld\n", q_pow(y, z, p)); } else if(op == 2) { if(y%p == 0 && z%p != 0) printf("Orz, I cannot find x!\n"); else printf("%lld\n", (1LL* z * q_pow(y, p-2, p)) % p); } else if(op == 3) { int ans = BSGS(y, z, p); if(ans == -1) printf("Orz, I cannot find x!\n"); else printf("%d\n", ans); } } } return 0; }