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的问题了,这时候问题就转化成求几个多项式的最大公约数,其实这是个错误名称,应该是求多项式的最大公共多项式

无齿的借用了大神的模版: 模版来自: http://blog.csdn.net/acdreamers/article/details/12685099

#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<ll> G[1000 + 5];

const int MOD = 999983;

int k;

int num[1000 + 5][50 + 5];

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

ll quick(ll a,ll b) {
    ll ans = 1;
    while(b) {
        if(b&1) {
            ans = (ans * a)%MOD;
            b--;
        }
        b >>= 1;
        a = a * a%MOD;
    }
    return ans;
}

/*多项式求最大公共项*/
vector<ll> poly_gcd(vector<ll> a,vector<ll> b) {
    if(b.size() == 0)
        return a;
    int t = a.size() - b.size();
    vector<ll> c;
    for(int i=0;i<=t;i++) {
        ll 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;
    }
    ll p = -1;
    for(int i=0;i<a.size();i++) {
        if(a[i] != 0) {
            p = i;
            break;
        }
    }
    if(p >= 0) {
        for(ll i=p;i<a.size();i++)
            c.push_back(a[i]);
    }
    return poly_gcd(b,c);
}

int main() {
    while(scanf("%d",&k) == 1) {
        clear();
        for(int i=0;i<k;i++) {
            ll x;
            scanf("%I64d",&x);
            for(int j=0;j<x+1;j++) {
                ll a;
                scanf("%I64d",&a);
                G[i].push_back(a);
            }
        }
        if(k == 1) {
            if(G[0].size() > 1)
                puts("YES");
            else
                puts("NO");
            continue;
        }
        vector<ll> g = poly_gcd(G[0],G[1]);
        for(ll i=2;i<k;i++)
            g = poly_gcd(g,G[i]);
        if(g.size() > 1)
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}

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

时间: 2024-12-27 19:53:00

HDU3892 Common Roots 多项式欧几里德求最大公共多项式的相关文章

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

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

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

【LCA求最近公共祖先+vector构图】Distance Queries

Distance Queries 时间限制: 1 Sec  内存限制: 128 MB 题目描述 约翰的奶牛们拒绝跑他的马拉松,因为她们悠闲的生活不能承受他选择的长长的赛道.因此他决心找一条更合理的赛道.此题的输入于第一题相同,紧接着下一行输入一个整数K,以后K行为K个"距离问题".每个距离问题包括两个整数,就是约翰感兴趣的两个农场的编号,请你尽快算出这两地之间的距离. N个点,N-1条边 输入 第1行:两个分开的整数:N和M: 第2..M+1行:每行包括4个分开的内容,F1,F2,L,

多项式多点求值和插值

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

霍纳规则解决多项式的求值问题

霍纳规则用来简化朴素多项式的求值.它将一元n次多项式的求值问题转化为n个一次式. 霍纳规则是采用最少的乘法运算策略,求多项式A(x) = anxn+ an-1xn-1+...+ a1x + a0在x0处的值,该规则是A(x0)=(...((anx0+ an-1)x0+...+ a1)x0+ a0) 1 #include<stdio.h> 2 3 int horner(int a[], int x, int n); 4 5 int main() 6 { 7 int n; 8 scanf(&quo

多项式多点求值

给定一个\(n\)次多项式\(A(x)\)和\(m\)个值\(a_i\),求出对于\(任意i\in [0,m-1],A(a_i)\)的值 前置知识: 分治FFT 多项式除法 一般优化多项式要么倍增要么分治-- 然而这题看上去不像能倍增的亚子,所以就分治吧 考虑先将要求的点分为两部分 \(x[0]=\{x_0,x_1,--,x_{\frac{m}{2}}\},x[1]=\{x_{\frac{m}{2}+1},x_{\frac{m}{2}+2},--x_{m-1}\}\) 我们记\(p[0]=\pr

多项式细节梳理&amp;模板(多项式)

基础 很久以前的多项式总结 现在的码风又变了... FFT和NTT的板子 typedef complex<double> C; const double PI=acos(-1); void FFT(C*a,R op){ for(R i=0;i<N;++i) if(i<r[i])swap(a[i],a[r[i]]); for(R i=1;i<N;i<<=1){ C wn=C(cos(PI/i),sin(PI/i)*op),w=1,t; for(R j=0;j<