zoukankan      html  css  js  c++  java
  • POJ 1060 多项式乘法和除法取余

    Modular multiplication of polynomials
    Time Limit: 1000MS        Memory Limit: 10000K
    Total Submissions: 4516        Accepted: 2033

    Description
    Consider polynomials whose coefficients are 0 and 1. Addition of two polynomials is achieved by 'adding' the coefficients for the corresponding powers in the polynomials. The addition of coefficients is performed by addition modulo 2, i.e., (0 + 0) mod 2 = 0, (0 + 1) mod 2 = 1, (1 + 0) mod 2 = 1, and (1 + 1) mod 2 = 0. Hence, it is the same as the exclusive-or operation.

    (x^6 + x^4 + x^2 + x + 1) + (x^7 + x + 1) = x^7 + x^6 + x^4 + x^2

    Subtraction of two polynomials is done similarly. Since subtraction of coefficients is performed by subtraction modulo 2 which is also the exclusive-or operation, subtraction of polynomials is identical to addition of polynomials.

    (x^6 + x^4 + x^2 + x + 1) - (x^7 + x + 1) = x^7 + x^6 + x^4 + x^2

    Multiplication of two polynomials is done in the usual way (of course, addition of coefficients is performed by addition modulo 2).

    (x^6 + x^4 + x^2 + x + 1) (x^7 + x + 1) = x^13 + x^11 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + 1

    Multiplication of two polynomials f(x) and g(x) modulo a polynomial h(x) is the remainder of f(x)g(x) divided by h(x).

    (x^6 + x^4 + x^2 + x + 1) (x^7 + x + 1) modulo (x^8 + x^4 + x^3 + x + 1) = x^7 + x^6 + 1
    The largest exponent of a polynomial is called its degree. For example, the degree of x^7 + x^6 + 1 is 7.

    Given three polynomials f(x), g(x), and h(x), you are to write a program that computes f(x)g(x) modulo h(x).
    We assume that the degrees of both f(x) and g(x) are less than the degree of h(x). The degree of a polynomial is less than 1000.

    Since coefficients of a polynomial are 0 or 1, a polynomial can be represented by d+1 and a bit string of length d+1, where d is the degree of the polynomial and the bit string represents the coefficients of the polynomial. For example, x^7 + x^6 + 1 can be represented by 8 1 1 0 0 0 0 0 1.

    Input
    The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of three lines that contain three polynomials f(x), g(x), and h(x), one per line. Each polynomial is represented as described above.

    Output
    The output should contain the polynomial f(x)g(x) modulo h(x), one per line.

    Sample Input

    2
    7 1 0 1 0 1 1 1
    8 1 0 0 0 0 0 1 1
    9 1 0 0 0 1 1 0 1 1
    10 1 1 0 1 0 0 1 0 0 1
    12 1 1 0 1 0 0 1 1 0 0 1 0
    15 1 0 1 0 1 1 0 1 1 1 1 1 0 0 1

    Sample Output

    8 1 1 0 0 0 0 0 1

    14 1 1 0 1 1 0 0 1 1 1 0 1 0 0


    从后往前插
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    const int maxn=2010;
    //f,g,h存储的是多项式的系数,sum存储的是f*g的系数以及最后余数的系数
    int f[maxn],g[maxn],h[maxn],sum[maxn];
    int lf,lg,lh,ls;//分别为f,g,h,sum的最高次幂
    
    //比较sum表示的多项式与h表示的多项式的大小
    int compare() {
        if(ls<lh)
            return -1;
        if(ls>lh)
            return 1;
        for(int i=ls-1; i>=0; i--) { //如果最高次幂相等,则从高位向下依次比较
            if(sum[i]==h[i])
                continue;
            if(sum[i]>h[i])
                return 1;
            if(sum[i]<h[i])
                return -1;
        }
        return 0;
    }
    int main() {
        freopen("in.txt","r",stdin);
        int t,d;
        scanf("%d",&t);
        while(t--) {
            memset(h,0,sizeof(h));
            memset(sum,0,sizeof(sum));
            //将f多项式的信息存入f数组
            scanf("%d",&d);
            lf=d-1;
            for(int j=lf; j>=0; j--) {
                scanf("%d",&f[j]);
            }
            //将g多项式的信息存入g数组
            scanf("%d",&d);
            lg=d-1;
            for(int j=lg; j>=0; j--) {
                scanf("%d",&g[j]);
            }
            //将h多项式的信息存入h数组
            scanf("%d",&d);
            lh=d-1;
            for(int j=lh; j>=0; j--) {
                scanf("%d",&h[j]);
            }
            //计算f*g的多项式
            ls=lf+lg;
            for(int i=lf; i>=0; i--) {
                for(int j=lg; j>=0; j--) {
                    sum[i+j]=sum[i+j]^(f[i]&g[j]);
                }
            }
            /*
              关键是怎么求余数,这里是先判断sum多项式是否大于h多项式,
              若大于,则sum减一次h,减去后的信息存入sum中。
              再继续判断,直到sum小于h,则此时的sum为余数。
              总之,就是把除法改成较简单的减法操作。
            */
            while(compare()>=0) {
                d=ls-lh;
                for(int i=ls; i-d>=0; i--) {
                    sum[i]=sum[i]^h[i-d];
                }
                while(ls && !sum[ls])
                    ls--;
                /*
                原先一直WA的代码,在每次更新sum的最高次幂ls时出了错误。
                int mark=0;
                for(int i=ls; i-d>=0; i--) {
                    sum[i]=sum[i]^h[i-d];
    
                    下面错误错在这里只判断了i>=d的情况,
                    有可能当i>=d的时候sum[i]=0,这样求出mark(也就是结果的最高次幂)为0;
                    但是可能有i<d的时候,有sum[i]=1,那么mark就不为0。
    
                    if(sum[i] && !mark) {
                        mark=i;
                    }
    
                }
                ls=mark;
                */
    
            }
    
            printf("%d",ls+1);
            for(int i=ls; i>=0; i--) {
                printf(" %d",sum[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    
    


  • 相关阅读:
    Spring Boot将Mybatis返回结果转为驼峰的三种实现方式
    Lodash-一个好用的JavaScript工具库
    基于Docker搭建LNMP环境并启用ssl证书(certbot)
    CentOS忘记mariadb/mysql root密码解决办法
    Debian如何安装curl?
    SpringBoot Controller如何接收数组参数?
    nginx web服务器概念了解 配置
    c语言二维数组的转置
    顺序表有序插入数据
    elasticsearch master_not_discovered_exception
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/7256429.html
Copyright © 2011-2022 走看看