UVA - 10951 Polynomial GCD (最大公共多项式)

Description

Problem C

Polynomial GCD

Input: standard input

Output: standard output

Given two polynomials f(x) and g(x) in
Zn
, you have to find their GCD polynomial, ie, a polynomial
r(x) (also in Zn) which has the greatest degree of all the polynomials in
Zn that divide both f(x) and
g(x)
. There can be more than one such polynomial, of which you are to find the one with a leading coefficient of
1 (1 is the unity in Zn. Such polynomial is also called a
monic polynomial).

(Note: A function f(x) is in Zn means all the coefficients in
f(x) is modulo n.)

Input

There will be no more than 101 test cases. Each test case consists of three lines: the first line has
n, which will be a prime number not more than 1500. The second and third lines give the two polynomials
f(x) and g(x). The polynomials are represented by first an integer
D which represents the degree of the polynomial, followed by
(D + 1)
positive integers representing the coefficients of the polynomial. the coefficients are in decreasing order of Exponent. Input ends with
n = 0. The value of D won‘t be more than
100
.

Output

For each test case, print the test case number and r(x), in the same format as the input

Sample Input                                 Output for Sample Input

3 
3 2 2 1 1
4 1 0 2 22
0 
                    
Case 1: 2 1 2 1 

 


Problem setter: SadrulHabibChowdhury

Special Thanks: Derek Kisman, EPS

 

Note: The first sample input has 2x3 + 2x2 + x + 1
and x4 + 2x2 + 2x + 2 as the functions.

题意:求两个多项式的最大公共多项式

思路:套用了模板

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
typedef long long ll;
using namespace std;
const int maxn = 100005;

vector<int> G[maxn];
int mod;

int pow_mod(int a, int b) {
	int ans = 1;
	while (b) {
		if (b & 1)
			ans = ans * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	return ans;
}

/*多项式求最大公共项*/
vector<int> poly_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] * pow_mod(b[0],mod-2)%mod;
		for (ll j = 0; j < b.size(); j++)
			a[i+j] = (a[i+j] - tmp * b[j]%mod + mod)%mod;
	}
	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 poly_gcd(b,c);
}  

int main() {
	int cas = 1;
	while (scanf("%d", &mod) != EOF && mod) {
		for (int i = 0; i < 2; i++)
			G[i].clear();
		int a, b;

		for (int i = 0; i < 2; i++) {
			scanf("%d", &a);
			for (int j = 0; j <= a; j++) {
				scanf("%d", &b);
				G[i].push_back(b);
			}
		}

		vector<int> ans = poly_gcd(G[0], G[1]);
		printf("Case %d: %d", cas++, ans.size()-1);
		int cnt = pow_mod(ans[0], mod-2);
		for (int i = 0; i < ans.size(); i++) {
			ans[i] = ans[i] * cnt % mod;
			printf(" %d", ans[i]);
		}
		printf("\n");
	}
	return 0;
}
时间: 2024-08-01 03:28:52

UVA - 10951 Polynomial GCD (最大公共多项式)的相关文章

UVA 10951 Polynomial GCD 多项式欧几里德求最大公共多项式

今天作比赛遇上了HDU3892,都分析出来怎么做了,可惜不会求多项式的最大公共多项式,当时写了半天,案例也没有跑出来,赛后搜了一下题解,发现有大神做出了,而且是有模版的,不过又搜了一下关于这方面的题目,很少,只发现了这一道,所以先做一下这一道吧 题意,给你两个多项式,求他们的最大公共多项式,然后输出即可,无齿的套用了别人的模版,呵呵! #include<iostream> #include<cstdio> #include<list> #include<algor

UVA 10951 - Polynomial GCD(数论)

UVA 10951 - Polynomial GCD 题目链接 题意:给定两个多项式,求多项式的gcd,要求首项次数为1,多项式中的运算都%n,并且n为素数. 思路:和gcd基本一样,只不过传入的是两个多项式,由于有%n这个条件,所以计算过程可以用乘法逆去计算除法模,然后最后输出的时候每项除掉首项的次数就是答案了. 代码: #include <stdio.h> #include <string.h> #include <vector> using namespace s

uva 10951 - Polynomial GCD(欧几里得)

题目链接:uva 10951 - Polynomial GCD 题目大意:给出n和两个多项式,求两个多项式在所有操作均模n的情况下最大公约数是多少. 解题思路:欧几里得算法,就是为多项式这个数据类型重载取模运算符,需要注意的是在多项式除多项的过程中,为了保证各项系数为整数,需要将整个多项式的系数整体扩大至一定倍数,碰到先除后模的时候要用逆元. #include <cstdio> #include <cstring> const int maxn = 105; int M; void

HDU3892 Common Roots 多项式欧几里德求最大公共多项式

这就是数论坑的地方了把,有些题目真心偏到你无法想象,需要用到多项式欧几里德求多项式的最大公共多项式 题意:给你n个多项式,问他们有没有共同的根 先分析把,假设有多项式a,b,同时又有多项式k,r,令 a = k*b +r,应题目要求,令解为0,那么a = 0,同时b也要等于0,那么这时候要满足a=b=0 其实 r = 0,这时候就不需要去管k了,有没有发现跟那个扩展欧几里德有点相似的方程,这时候分析一下,肯定跟a,b,r有关系,同时因为他们有共同的根,所以可以把问题转化成b,r的问题了,这时候问

【数论】UVa 10586 - Polynomial Remains

Problem F: Polynomial Remains Given the polynomial a(x) = an xn + ... + a1 x + a0, compute the remainder r(x) when a(x) is divided by xk+1. The input consists of a number of cases. The first line of each case specifies the two integers n and k (0 ≤ n

UVa 1642 - Magical GCD(数论)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4517 题意: 输入一个n(n≤100000)个元素的正整数序列,求一个连续子序列,使得该序列中所有元素的最大公约数与序列长度的乘积最大.例如,5个元素的序列30, 60, 20, 20, 20的最优解为{60, 20, 20, 20},乘积为gcd(60,20,20,20)*4=8

UVa 1642 Magical GCD (暴力+数论)

题意:给出一个长度在 100 000 以内的正整数序列,大小不超过 10^ 12.求一个连续子序列,使得在所有的连续子序列中, 它们的GCD值乘以它们的长度最大. 析:暴力枚举右端点,然后在枚举左端点时,我们对gcd相同的只保留一个,那就是左端点最小的那个,只有这样才能保证是最大,然后删掉没用的. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include

UVA 11827 Maximum GCD

题目很水 暴力就能过 难点在如何输入没有停止的数 #include <iostream> #include <string.h> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <sstream> using namespace std; int gcd (int a,int b) { if(b==0) return a; else return gc

UVA - 11827 - Maximum GCD,10200 - Prime Time (数学)

两个暴力题.. 题目传送:11827 Maximum GCD AC代码: #include <map> #include <set> #include <cmath> #include <deque> #include <queue> #include <stack> #include <cstdio> #include <cctype> #include <string> #include <