uva 10951 - Polynomial GCD(欧几里得)

题目链接:uva 10951 - Polynomial GCD

题目大意:给出n和两个多项式,求两个多项式在所有操作均模n的情况下最大公约数是多少。

解题思路:欧几里得算法,就是为多项式这个数据类型重载取模运算符,需要注意的是在多项式除多项的过程中,为了保证各项系数为整数,需要将整个多项式的系数整体扩大至一定倍数,碰到先除后模的时候要用逆元。

#include <cstdio>
#include <cstring>

const int maxn = 105;
int M;

void gcd (int a, int b, int& d, int& x, int& y) {
    if (b == 0) {
        d = a;
        x = 1;
        y = 0;
    } else {
        gcd(b, a%b, d, y, x);
        y -= (a/b) * x;
    }
}

int inv (int a, int b) {
    int d, x, y;
    gcd(a, b, d, x, y);
    return (x + b) % b;
}

struct state {
    int d;
    int x[maxn];

    state() {
        d = 0;
        memset(x, 0, sizeof(x));
    }

    void get () {
        scanf("%d", &d);
        for (int i = d; i >= 0; i--)
            scanf("%d", &x[i]);
    }

    void put () {
        printf(" %d", d);
        for (int i = d; i >= 0; i--)
            printf(" %d", x[i]);
    }

    state operator * (const int& a) {
        state ans = *this;
        for (int i = 0; i <= d; i++)
            ans.x[i] = ans.x[i] * a % M;
        ans.del();
        return ans;
    }

    state operator - (const state& a) {

        state ans = *this;
        for (int i = 0; i <= a.d; i++)
            ans.x[d-i] = (ans.x[d-i] - a.x[a.d-i] + M) % M;
        ans.del();
        return ans;
    }

    void del () {
        for (int i = d; i >= 0; i--)
            x[d] = (x[d] + M) % M;

        while (d > 0 && x[d] == 0)
            d--;
    }

    bool empty() {
        return d <= 0 && x[0] == 0;
    }
};

state mod (state a, state b) {
    for (int i = a.d; i >= b.d; i--) {
        int p = a.x[i], q = b.x[b.d];

        state c = b * inv(q, M) * p;;
        a = a - c;
        /*
        a.put();
        printf("\n");
        */
    }
    return a;
}

state sgcd (state a, state b) {
    return b.empty() ? a : sgcd(b, mod(a, b));
}

int main () {
    int cas = 1;
    while (scanf("%d", &M) == 1 && M) {
        state a, b;
        a.get();
        b.get();

        state c = sgcd(a, b);

        printf("Case %d:", cas++);
        c = c * inv(c.x[c.d], M);
        c.put();
        printf("\n");
    }
    return 0;
}

uva 10951 - Polynomial GCD(欧几里得)

时间: 2024-08-04 10:16:23

uva 10951 - Polynomial GCD(欧几里得)的相关文章

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 多项式欧几里德求最大公共多项式

今天作比赛遇上了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

UVA 10090 - Marbles 拓展欧几里得

I have some (say, n) marbles (small glass balls) and I am going to buy some boxes to store them. Theboxes are of two types:T ype 1: each box costs c1 Taka and can hold exactly n1 marblesT ype 2: each box costs c2 Taka and can hold exactly n2 marblesI

UVA - 1347 Tour 双调欧几里得旅行商问题

题目大意:给出n个点,要求你从最左边那个点走到最右边那个点,每个点都要被遍历过,且每个点只能走一次,问形成的最短距离是多少 解题思路:用dp[i][j]表示第一个人走到了第i个点,第二个人走到了第j个点且已经遍历了1–max(i,j)的所有点的最短距离.因为dp[i][j] = dp[j][i]的,所以我们设i > j的 那么就有 当j < i-1 时,dp[i][j] = dp[i-1][j] + dis(i, i -1) 当j == i + 1时情况就比较特别了,这里将j用i-1代替 dp

UVa 12169 (枚举+扩展欧几里得) Disgruntled Judge

题意: 给出四个数T, a, b, x1,按公式生成序列 xi = (a*xi-1 + b) % 10001 (2 ≤ i ≤ 2T) 给出T和奇数项xi,输出偶数项xi 分析: 最简单的办法就是直接枚举a.b,看看与输入是否相符. 1 #include <cstdio> 2 3 const int maxn = 10000 + 5; 4 const int M = 10001; 5 int T, x[maxn]; 6 7 int main() 8 { 9 //freopen("12

Play with Floor and Ceil UVA - 10673(拓展欧几里得)

因为我现在还不会用这个...emm...蒟蒻...只看了 从来没用过....所以切一道水题...练一下... 人家讲的很好  https://blog.csdn.net/u012860428/article/details/41259377 题目大意:求出满足要求的p和q,使得对于给定的x,k,,输出一组满足要求的p,q即可: 下面对于x,k进行讨论: 1.若x能被k整除,那么只要p+q=k即可: 2.如果不能被其整除,则领,那么,x=p*a+q*(a+1);相当于对于不定方程求解,易知,(a,

Disgruntled Judge UVA - 12169(扩展欧几里得应用+暴力)

题目给我们的输入数值都是序列中的单数项,我们已知递推公式xi=(aXi-1 + b)mod10001, 所以我们可以将X2表示为X2=(aX1 + b)mod10001,将X3表示为X3=(aX2 + b)mod10001 然后将X2的式子带入到X3中得:X3=(a(aX1 + b)mod10001 + b)mod10001 X3=(a(aX1 + b)+ b)mod10001 X3+10001*k=a*a*X1+a*b+b 10001(-k)+(a+1)b=X3-a*a*X1 --1式 推导出

uva 1347 - Tour(双调欧几里得)

题目大意:给出n个点,确定一条 连接各点的最短闭合旅程的问题. 解题思路:dp[i][j]表示说从i联通到1,再从1联通到j的距离. dp[i][j] = dp[i-1][j] + dis(i,i-1); dp[i][i-1] = min (dp[i][i-1], dp[i-1][j] + dis(i, j)); 记忆化代码: //0 KB 58 ms #include<cstdio> #include<iostream> #include<cstring> #incl