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;
    }
    
    


  • 相关阅读:
    高可靠JAVA项目
    C语言JS引擎
    星际争霸,FF反作弊对战平台
    【转】ffluos编译
    〓经典文字武侠游戏 书剑 书剑江湖自由度超高!公益服!〓
    全局解释器锁GIL
    创建多线程Thread
    线程的简述Thread
    进程池的回调函数callback
    进程池的同步与异步用法Pool
  • 原文地址:https://www.cnblogs.com/mingrigongchang/p/6246278.html
Copyright © 2011-2022 走看看