Mr. Panda and Kakin(拓展欧几里得 + O(1)快速乘)
生活随笔
收集整理的這篇文章主要介紹了
Mr. Panda and Kakin(拓展欧几里得 + O(1)快速乘)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Mr. Panda and Kakin
給定n,cn, cn,c,要我們找到nnn是兩個相鄰質數的乘積,要我們找到xxx,滿足x230+3≡c(modn)x ^{2 ^{30} + 3} \equiv c \pmod nx230+3≡c(modn),1010≤n≤1018,0<c<n10 ^{10} \leq n \leq 10 ^ {18}, 0 < c < n1010≤n≤1018,0<c<n,
考慮得到230+32 ^{30} + 3230+3模?(n)\phi(n)?(n)下的逆元,為inv=(230+3)?(n)?1inv = (2 ^{30} + 3) ^{\phi(n) - 1}inv=(230+3)?(n)?1,則有cinv≡x(230+3)inv≡x(modn)c ^{inv} \equiv x ^{(2^{30} + 3)inv} \equiv x \pmod{n}cinv≡x(230+3)inv≡x(modn),使用O(1)O(1)O(1)快速乘即可。
#include <bits/stdc++.h>using namespace std;long long n, c, phi, inv;inline long long mul(long long x, long long y, long long mod) {return (x * y - (long long)((long double)x / mod * y) * mod + mod) % mod; }long long exgcd(long long a, long long b, long long & x, long long & y) {if(!b) {x = 1, y = 0;sreturn a;}long long gcd = exgcd(b, a % b, x, y);long long temp = x;x = y;y = temp - a / b * y;return gcd; }long long quick_pow(long long a, long long n, long long mod) {long long ans = 1;while (n) {if (n & 1) {ans = mul(ans, a, mod);}a = mul(a, a, mod);n >>= 1;}return ans; }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);int T, cas = 0;scanf("%d", &T);while (T--) {scanf("%lld %lld", &n, &c);long long p = sqrt(n), q;while (true) {if (n % p == 0) {break;}p--;}q = n / p;phi = (p - 1) * (q - 1);exgcd((1ll << 30) + 3, phi, inv, p);inv = ((inv % phi) + phi) % phi;printf("Case %d: %lld\n", ++cas, quick_pow(c, inv, n));}return 0; }總結
以上是生活随笔為你收集整理的Mr. Panda and Kakin(拓展欧几里得 + O(1)快速乘)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 眼睛化妆技巧 给大家推荐
- 下一篇: 马甲线是什么意思 马甲线意思简述