1. 程式人生 > >HDU3892(多項式域歐幾里德演算法)

HDU3892(多項式域歐幾里德演算法)

題意:給出n個多項式,如果它們模999983等於0的所有根中有相同的就輸出“YES”,否則輸出“NO”。

分析:假設有多項式a和多項式b,如果a = q*b + r,假設a和b有公共的根x,則取x的時候,a = q*b + r = 0且b = 0.

所以此時r也等於0. 所以a, b, r有同根x,這樣a,b的問題,就變成b,r的問題了。然後就是求最大公約數問題了。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <vector>

using namespace std;
typedef long long LL;
const LL MOD = 999983;

vector<LL> p[505];
int T;

LL quick_mod(LL a,LL b,LL m)
{
    LL ans = 1;
    a %= m;
    while(b)
    {
        if(b&1)
        {
            ans = ans*a%m;
            b--;
        }
        b>>=1;
        a=a*a%m;
    }
    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(LL i=0; i<=t; i++)
    {
        LL tmp = a[i] * quick_mod(b[0],MOD-2,MOD) % 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(LL 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);
}

bool Import()
{
    LL n,t;
    if(scanf("%d",&T) == 1)
    {
        for(LL i=0;i<T;i++)
        {
            p[i].clear();
            scanf("%I64d",&n);
            for(LL j=0;j<=n;j++)
            {
                scanf("%I64d",&t);
                p[i].push_back(t);
            }
        }
        return true;
    }
    return false;
}

void Work()
{
    if(T==1)
    {
        if(p[0].size() > 1) puts("YES");
        else puts("NO");
        return;
    }
    vector<LL> v = poly_gcd(p[0],p[1]);
    LL i = 2;
    while(i < T && v.size() > 1)
    {
        v = poly_gcd(v,p[i]);
        i++;
    }
    if(v.size() > 1) puts("YES");
    else puts("NO");
}

int main()
{
    while(Import())
        Work();
    return 0;
}

相關推薦

HDU3892(多項式演算法)

題意:給出n個多項式,如果它們模999983等於0的所有根中有相同的就輸出“YES”,否則輸出“NO”。 分析:假設有多項式a和多項式b,如果a = q*b + r,假設a和b有公共的根x,則取x的時候,a = q*b + r = 0且b = 0. 所以此時r也等於0

同餘方程(擴充套件演算法

同餘方程 時間限制: 1 Sec  記憶體限制: 128 MB 題目描述 求關於 x 的同餘方程 ax ≡ 1 (mod b)的最小正整數解。 輸入 輸入只有一行,包含兩個正整數 a, b,用一個空格隔開。 輸出 輸出只有一行,包含

Luogu4433:[COCI2009-2010#1] ALADIN(類演算法)

先套用一個線段樹維護離散化之後的區間的每一段的答案 那麼只要考慮怎麼下面的東西即可 ∑

caioj 1153 擴充套件演算法(解不定方程)

模板題 注意exgcd函式要稍微記一下 #include<cstdio> #include<cctype> #include<algorithm> #define

擴充套件的演算法-HDU2669

The Sky is Sprite.  The Birds is Fly in the Sky.  The Wind is Wonderful.  Blew Throw the Trees  Trees are Shaking, Leaves are Fal

數論-擴充套件演算法

找出一對整數(x,y),使得ax+by=gcd(a,b)。注意,這裡的x和y不一定是正數,也可能是負數或者0.例如,gcd(6,15)=3,6*3-15*1=3,其中,x=3,y=-1.這個方程還有其他解,如x=-2,y=1。 用數學歸納法並不難證明演算法的正確性。此處略去

演算法學習(一)——演算法&擴充套件演算法

最大公約數/歐幾里德演算法(gcd) 歐幾里德演算法又稱輾轉相除法,證明可以度娘。 個人簡單腦部就是a和b兩個數的模還是a和b的最大公約數 int型別  int gcd(int a, int b) {return a%b==0?b:gcd(b,a%b);} long l

拓展演算法的求解證明及基本應用

拓展歐幾里德要解決的問題就是給定方程 a x +

擴充套件演算法求解線性同餘方程

 歐幾里德演算法  歐幾里德演算法又稱輾轉相除法,用於計算兩個整數a,b的最大公約數。其計算原理依賴於下面的定理:  定理:gcd(a,b) = gcd(b,a mod b)  證明:a可以表示成a = kb + r,則r = a mod b  假設d是a,b的一個公約數,則

演算法的推導與證明 || 擴充套件演算法的解釋說明

序言:      當博主第一次見到歐幾里德演算法時,我是不屑一顧的,由於模板比較好背,所以也沒有仔細研究過其中的數學原理.這段時間突然喜歡上了數學,碰巧同學講了一下基礎數論,就去聽了一聽. 由於博主數學基礎和學習能力都比較差,沒有立即消化其中的知識,於是研究

擴充套件演算法 遞迴和非遞迴實現及證明

關於歐幾里得演算法,貝祖等式,擴充套件歐幾里得演算法,Wikipedia的解釋非常非常詳細了。 另外,看了好多別人優秀的總結,我認為最詳盡的就是ACM之家的總結。 這裡自己再總結一次…實際上就是把別人總結的,我認為有助於自己理解的內容copy過來,再加上

擴充套件的演算法求乘法逆元

計算乘法逆元,比如3mod8的乘法逆元為3 是如何用歐幾里得演算法計算的呢??? 數對 x,y ,使得 gcd(a,b)=ax+by。 c++語言實現: #include <iostream&

演算法(Euclidean algorithm)

設兩數為a、b(a>b),用gcd(a,b)表示a,b的最大公約數,r=a (mod b) ,k=a/b(整除),即a÷b=k.......r。 1:令c=gcd(a,b),則設a=mc,b=nc // 因為c是最大公約數 2:根據a÷b=k.......r,可列k*b+r=a,代入a,b,解得

gcd演算法/extgcd擴充套件演算法以及在解不定方程中的應用

這個應該是我在noip前就應該會的東西 ,但是當時也許只是記下了程式碼吧 ,現在有諸多的不理解。後來藉著書和幾篇部落格弄懂了並小證了一下,鑑於網上有些部落格關於這個的寫的真的不好看,所以自己來總結一下,順帶以後也能看。 順帶一提,gcd(a,b)表示a,b的最

對於拓展演算法的理解

上面的思想是以遞迴定義的,因為 gcd 不斷的遞迴求解一定會有個時候 b=0,所以遞迴可以結束。 對於上述說明,可以給道題目幫助理解: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=10755先說一下大概題意:有兩隻青蛙,一隻在座標x,

演算法複雜度分析

歐幾里得演算法 function Euclid(a; b) 1: if b = 0 then 2: return a; 3: end if 4: return Euclid(b; a mod b)

C語言輾轉相除法(演算法)求最大公約數

演算法敘述: 設(a,b)表示a和b的最大公約數 若c為a/b的餘數(c=a%b) 則(a,b)=(b,c). #include<stdio.h> int gcd(int a,int b

擴充套件演算法模版題(求逆元+分析+題目)HDU1576 A/B

首先給大家普及一下什麼是擴充套件歐幾里德演算法,它是由歐幾里德演算法演變的,即我們常說的輾轉相除法。 程式碼如下: int gcd(int a,int b){ return b?gcd(b,a%b):a; } 那麼對於不完全為0的非負整數,a,b,gcd(a,b

#數論# 演算法 、擴充套件演算法 、費馬小、逆元求解(ing)

歐幾里德求gcd(輾轉相除法): 定理: gcd(a, b) = gcd(b, a % b) 兩個正整數a和b(a>b),它們的最大公約數等於a除以b的餘數c和b之間的最大公約數 證明: a可以表示成a = kb + r,則r = a %