二次剩余
素数模的二次同余方程
求解
x * x = a(mod p) p为奇素数,输出 x 的可行解
// 输入 a 和 mod ,满足式子 x * x = a(mod p) p为奇素数,输出 x 的可行解 #include<cstdio> using namespace std; #define LL long long LL Pow(LL a,LL b,LL p) { LL res = 1; for (; b; a = 1LL * a * a % p, b >>= 1) if (b & 1) res = 1LL * a * res % p; return res; } bool Legendre(LL a,LL p) { return Pow(a, p - 1 >> 1, p) == 1; } void modsqr(LL a,LL p) { LL x; LL i, k, b; if (p == 2) x = a % p; else if (p % 4 == 3) x = Pow(a, p + 1 >> 2, p); else { for (b = 1; Legendre(b, p); ++b); i = p - 1 >> 1; k = 0; do { i >>= 1; k >>= 1; if (!((1LL * Pow(a, i, p) * Pow(b, k, p) + 1) % p)) k += p - 1 >> 1; } while (!(i & 1)); x = 1LL * Pow(a, i + 1 >> 1, p) * Pow(b, k >> 1, p) % p; } if (p - x < x) x = p - x; if (x == p - x) printf("%lld\n", x); // 输出解 else printf("%lld %lld\n", x, p - x); } int main() { int T; scanf("%d", &T); LL a, p; while (T--) { scanf("%lld %lld", &a, &p); a %= p; if (!Legendre(a, p)) { puts("No root"); continue; } modsqr(a, p); } return 0; }
牛客第九场Quadratic equation
#include<cstdio> using namespace std; const long long mod = 1e9 + 7; #define LL long long LL B,C; LL Pow(LL a,LL b,LL p) { LL res = 1; for (; b; a = 1LL * a * a % p, b >>= 1) if (b & 1) res = 1LL * a * res % p; return res; } bool Legendre(LL a,LL p) { return Pow(a, p - 1 >> 1, p) == 1; } bool check(LL b,LL x) { if ((b + x) % 2 == 1) return false; LL xx = (x + b) / 2; LL yy = (b - x) / 2; if (0 <= xx && xx < mod && 0 <= yy && yy < mod) return true; return false; } void modsqr(LL a,LL p) { LL x; LL i, k, b; if (p == 2) x = a % p; else if (p % 4 == 3) x = Pow(a, p + 1 >> 2, p); else { for (b = 1; Legendre(b, p); ++b); i = p - 1 >> 1; k = 0; do { i >>= 1; k >>= 1; if (!((1LL * Pow(a, i, p) * Pow(b, k, p) + 1) % p)) k += p - 1 >> 1; } while (!(i & 1)); x = 1LL * Pow(a, i + 1 >> 1, p) * Pow(b, k >> 1, p) % p; } if (p - x < x) x = p - x; if (x == p - x) { if (check(B, x)) printf("%lld %lld\n", (B - x) / 2, (B + x) / 2); else if (check(B + p, x)) printf("%lld %lld\n", (B + p - x) / 2, 1LL * (B + p + x) / 2); else puts("-1 -1"); } else { if (check(B, x)) printf("%lld %lld\n", (B - x) / 2, (B + x) / 2); else if (check(B, p - x)) printf("%lld %lld\n", (B - p + x) / 2, (B - x + p) / 2); else if (check(B + p, x)) printf("%lld %lld\n", (B - x + p) / 2, (B + x + p) / 2); else if (check(B + p, p - x)) printf("%lld %lld\n", (B + x) / 2, (B - x + 2 * p) / 2); else puts("-1 -1"); } } int main() { int T; scanf("%d", &T); LL a; while (T--) { scanf("%lld %lld", &B, &C); a = (B * B % mod - 4LL * C % mod + mod); a %= mod; if (a == 0) { if (B % 2 == 0) printf("%lld %lld\n", B / 2, B / 2); else printf("%lld %lld\n", (B + mod) / 2, (B + mod) / 2); continue; } if (!Legendre(a, mod)) { puts("-1 -1"); continue; } modsqr(a, mod); } return 0; }