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

今天作比赛遇上了HDU3892,都分析出来怎么做了,可惜不会求多项式的最大公共多项式,当时写了半天,案例也没有跑出来,赛后搜了一下题解,发现有大神做出了,而且是有模版的,不过又搜了一下关于这方面的题目,很少,只发现了这一道,所以先做一下这一道吧

题意,给你两个多项式,求他们的最大公共多项式,然后输出即可,无齿的套用了别人的模版,呵呵!

#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>

#define ll long long
#define LL __int64
#define eps 1e-8

//const ll INF=9999999999999;

#define inf 0xfffffff

using namespace std;

//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;

vector<int> G[100000 + 5];

int MOD;

void clear() {
	for(int i=0;i<2;i++)
		G[i].clear();
}

int quick(int a,int b) {
	int ans = 1;
	while(b) {
		if(b&1) {
			ans = (ans * a)%MOD;
			b--;
		}
		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] * quick(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 Case = 0;
	while(scanf("%d",&MOD),MOD) {
		clear();
		int x;
		for(int i=0;i<2;i++) {
			scanf("%d",&x);
			for(int j=0;j<x+1;j++) {
				int a;
				scanf("%d",&a);
				G[i].push_back(a);
			}
		}
		vector<int> ans = poly_gcd(G[0],G[1]);
		printf("Case %d: %d",++Case,ans.size() - 1);
		int tmp = ans[0];
		for(int i=0;i<ans.size();i++) {
			ans[i] = ans[i] * quick(tmp,MOD - 2)%MOD;
			printf(" %d",ans[i]);
		}
		puts("");
	}
	return 0;
}

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

时间: 2024-10-24 12:11:20

UVA 10951 Polynomial GCD 多项式欧几里德求最大公共多项式的相关文章

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 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

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 polynomia

HDU 5768Lucky7(多校第四场)容斥+中国剩余定理(扩展欧几里德求逆元的)+快速乘法

地址:http://acm.hdu.edu.cn/showproblem.php?pid=5768 Lucky7 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 754    Accepted Submission(s): 279 Problem Description When ?? was born, seven crows flew

One Person Game(扩展欧几里德求最小步数)

One Person Game Time Limit: 2 Seconds      Memory Limit: 65536 KB There is an interesting and simple one person game. Suppose there is a number axis under your feet. You are at point A at first and your aim is point B. There are 6 kinds of operations

多项式多点求值和插值

本文以存板子为主= = 对于比较一般的情况,n次多项式在n个点求值和用n个点插值可以做到,并且这也是下界. 多项式多点求值 给一个多项式F和一堆值,求出. 设,. 那么对于,,对于,.递归即可. 多项式多点插值 给一堆值.,要求求出一个n-1次多项式满足. 考虑拉格朗日插值:. 我们先考虑对于每个i,如何求出.设,那么我们就是要求. 取的时候这个式子分子分母都为0,那么我们可以用洛必达法则,这个式子就等于.那么我们可以用多点求值求出每个. 设为,现在我们就是要求,显然可以分治FFT. 具体地,还

UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)

UVA 572 -- Oil Deposits(DFS求连通块) 图也有DFS和BFS遍历,由于DFS更好写,所以一般用DFS寻找连通块. 下述代码用一个二重循环来找到当前格子的相邻8个格子,也可用常量数组或者写8条DFS调用. 下述算法是:种子填充(floodfill) 两种连通区域 四连通区域:从区域内一点出发,可通过上.下.左.右四个方向的移动组合,在不越出区域的前提下,能到达区域内的任意像素 八连通区域:从区域内每一像素出发,可通过八个方向,即上.下.左.右.左上.右上.左下.右下移动的

UVA 816 -- Abbott&#39;s Revenge(BFS求最短路)

 UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉点的方向(用NEWS表示不同方向)不同时, 允许出去的方向也不相同. 例如:1 2 WLF NR ER * 表示如果 进去时朝W(左), 可以 左转(L)或直行(F), 如果 朝N只能右转(R) 如果朝E也只能右转.* 表示这个点的描述结束啦! 输入有: 起点的坐标, 朝向, 终点的坐标.然后是各个