求多项式的最大公约数
模板题:https://cn.vjudge.net/problem/UVA-10951#author=0
给定两个Zn上的多项式f和g,求出它们的gcd,并且次数尽量大,最高项系数为1(加法和乘法均在mod m意义下进行)
#include <stdio.h> #include <string.h> #include <vector> using namespace std; int n; vector<int> f, g; // 快速幂求逆元 int inv(int a, int n) { int res = 1; int b = n-2; while(b) { if(b & 1) res = res * a % n; a = a * a % n; b >>= 1; } return res; } //多项式的最大公约数 vector<int> gcd(vector<int> a,vector<int> b) { if(b.size() == 0) return a; int t = a.size() - b.size(); vector<int> c; for(int i=0; i<=t; i++) { int tmp = a[i] * inv(b[0],n) % n; for(int j=0; j<b.size(); j++) a[i+j] = (a[i+j] - tmp * b[j] % n + n) % n; } int p = -1; for(int i=0; i<a.size(); i++) { if(a[i] != 0) { p=i; break; } } if(p >= 0) for(int i=p; i<a.size(); i++) c.push_back(a[i]); return gcd(b,c); } int main() { int cas = 0; while (~scanf("%d", &n) && n) { f.clear(); g.clear(); int a, k; scanf("%d", &a); for (int i = 0; i <= a; i++) { scanf("%d", &k); f.push_back(k); } scanf("%d", &a); for (int i = 0; i <= a; i++) { scanf("%d", &k); g.push_back(k); } vector<int> ans = gcd(f, g); int tmp = inv(ans[0], n), ansz = ans.size(); printf("Case %d: %d", ++cas, ansz - 1); for (int i = 0; i < ansz; i++) { printf(" %d", ans[i] * tmp % n); } printf(" "); } return 0; }