zoukankan      html  css  js  c++  java
  • uva 10951

    题目链接: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("
    ");
            */
        }
        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("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Redis教程16-服务器
    剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
    剑指 Offer 18. 删除链表的节点
    剑指 Offer 16. 数值的整数次方
    通过GetLastError 获取win32 api 的错误信息
    Windows API 错误码
    VS2012程序打包部署详解
    C#中子类调用父类的实现方法
    获取有关编程语言的帮助?
    Windows API 错误码解析
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3944617.html
Copyright © 2011-2022 走看看