您的位置:首页 > 其它

POJ 1060/ ZOJ 1026 : Modular Multiplication of Polynomials - f(x)g(x) mod h(x)

2015-01-10 21:47 447 查看
多项式乘法、模除

题意:

给出f(x),g(x),h(x)的 (最高次幂+1)的值,以及它们的各项系数,求f(x)*g(x)/h(x)的余数。

这里多项式的系数只有1或0,

因为题目要求:这里多项式的加减法是将系数相加/减后再模2,这样其实也就可以用异或运算来代替加减法。

思路:

主要在于把除法转化成减法,一次一次减。

用sum[]数组存结果,最高次幂为ls,各项系数存在f[ls-1 … 0]

1 - 计算乘积,

多项式的系数只有1或0,故最高次幂ls = lf + lg -1,f[i]*g[j](i、j为指数的值),相当于位的与运算f[i]&g[j],结果加到x^(i+j)的系数上,即sum[i+j]+=f[i]&g[j];

2 - 计算模除。

sum(x)对h(x)取模,即除以h(x)直到余数小于h(x),此余数即取模的结果,关键在于判别sum(x)、h(x)的大小。

若ls>lh,则sum大;让sum(x)除以h(x):

对h,按次幂由低到高,进行相除运算,h[i]异或到sum[i+ls-lh],即sum[i+d] ^= h[i],然后重新调整sum的最高次幂(while(ls&&!sum[ls-1])-ls)

ls<lh,则h大,得到结果;

若ls=lh,从最高次幂开始逐项比较系数。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1005;

int cmp(int a[], int la, int b[], int lb){//比较多项式a b的大小
if(la > lb)
return 1;
if(la < lb)
return -1;
for(int i = la - 1; i >= 0; i--){//a b最高次幂相同时,按次幂由高到低顺序逐项比较
if(a[i] && !b[i])
return 1;
else if(!a[i] && b[i])
return -1;
}
return 0;
}

int main(){
int t;
scanf("%d", &t);
while(t--){
int f
, g
, h
;
int lf, lg, lh;

scanf("%d", &lf);//多项式最高次幂
for(int i = lf - 1; i >= 0; i--)//多项式每一项的系数
scanf("%d", &f[i]);
scanf("%d", &lg);
for(int i = lg - 1; i >= 0; i--)
scanf("%d", &g[i]);
scanf("%d", &lh);
for(int i = lh - 1; i >= 0; i--)
scanf("%d", &h[i]);

int sum[N + N], ls = lf + lg - 1;//乘积数组sum、长度初始化
for(int i = 0; i < ls; i++)
sum[i] = 0;
for(int i = 0; i < lf; i++)
for(int j = 0; j < lg; j++)
sum[i + j] ^= (f[i] & g[j]);

//取模
while(cmp(sum, ls, h, lh) >= 0){//当前余数sum不小于h,则继续除以h
int d = ls - lh;
for(int i = 0; i < lh; i++)
sum[i + d] ^= h[i];
while(ls && !sum[ls - 1])
ls--;
}

/*if(ls == 0)//舍去这部分无碍
ls = 1;*/
printf("%d ", ls);
for(int i = ls - 1; i > 0; i--)
printf("%d ", sum[i]);
printf("%d\n", sum[0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多项式 数学 poj zoj