給定兩個模素數 n 的多項式 f(x), g(x),求它們的最大公因式,並將首項係數規範為 1(即乘以首項係數的模逆)。
同整數 GCD,但除法在模 n 意義下進行。關鍵步驟:
a⁻¹ mod n。f mod g。令首項係數比為 k = f.lead * g.lead⁻¹ mod n,用 f - k·x^(deg f - deg g)·g 消去 f 的最高次項,重複直到次數 < g。gcd(f,g) = gcd(g, f mod g),直到 g 為零多項式。#include <bits/stdc++.h> using namespace std; int n; vectorf, g; int exgcd(int a, int b, int &x, int &y) { if (!b) { x=1; y=0; return a; } int d = exgcd(b, a%b, y, x); y -= a/b * x; return d; } int inv(int a, int n) { int x, y; exgcd(a, n, x, y); return (x % n + n) % n; } vector pmod(vector f, vector g) { int fz = f.size(), gz = g.size(); for (int i = 0; i < fz; i++) { int k = fz - i - gz; if (k < 0) break; int coeff = (long long)f[i] * inv(g[0], n) % n; for (int j = 0; j < gz; j++) { int pos = i + j; f[pos] = ((f[pos] - (long long)coeff * g[j]) % n + n) % n; } } // 去除前導零 vector res; int p = -1; for (int i = 0; i < fz; i++) if (f[i]) { p=i; break; } if (p >= 0) for (int i = p; i < fz; i++) res.push_back(f[i]); return res; } vector pgcd(vector f, vector g) { if (g.empty()) return f; return pgcd(g, pmod(f, g)); } int main() { int cas = 0; while (cin >> n, n) { f.clear(); g.clear(); int deg, coef; cin >> deg; for (int i = 0; i <= deg; i++) { cin >> coef; f.push_back(coef); } cin >> deg; for (int i = 0; i <= deg; i++) { cin >> coef; g.push_back(coef); } vector ans = pgcd(f, g); int lead_inv = inv(ans[0], n); cout << "Case " << ++cas << ": " << ans.size() - 1; for (int c : ans) cout << ' ' << (long long)c * lead_inv % n; cout << '\n'; } return 0; }
vector 低位在前(常數項索引 0),或高位在前?代碼中 f[0] 為最高次項係數(輸入順序)。注意一致性。多項式 GCD 是整數 GCD 在多項式環上的直接推廣。關鍵在於模素數域上除法可行(非零元可逆),利用模逆實現多項式長除法。代碼簡潔,體現代數結構的統一性。