1 条题解

  • 0
    @ 2025-5-13 14:08:01

    问题分析:

    输入包含多个测试用例,每个测试用例有三个多项式,需要计算前两个多项式相乘后对第三个多项式取模的结果。多项式用特定格式表示,即先给出多项式的次数,然后是系数组成的位串。计算多项式乘法:设f(x)=i=0maixif(x)=\sum_{i = 0}^{m}a_{i}x^{i}g(x)=j=0nbjxjg(x)=\sum_{j = 0}^{n}b_{j}x^{j},其中ai,bj{0,1}a_{i},b_{j}\in\{0,1\}。对于多项式乘法f(x)g(x)=k=0m+nckxkf(x)g(x)=\sum_{k = 0}^{m + n}c_{k}x^{k},其中ck=i+j=kaibjmod2c_{k}=\sum_{i + j=k}a_{i}b_{j}\bmod 2。例如,对于f(x)=x6+x4+x2+x+1f(x)=x^{6}+x^{4}+x^{2}+x + 1(可表示为6 1 0 1 0 1 1 16\ 1\ 0\ 1\ 0\ 1\ 1\ 1

    问题分析:

    输入包含多个测试用例,每个测试用例有三个多项式,需要计算前两个多项式相乘后对第三个多项式取模的结果。多项式用特定格式表示,即先给出多项式的次数,然后是系数组成的位串。

    计算多项式乘法:

    f(x)=i=0maixif(x)=\sum_{i = 0}^{m}a_{i}x^{i}g(x)=j=0nbjxjg(x)=\sum_{j = 0}^{n}b_{j}x^{j},其中ai,bj{0,1}a_{i},b_{j}\in\{0,1\}

    对于多项式乘法f(x)g(x)=k=0m+nckxkf(x)g(x)=\sum_{k = 0}^{m + n}c_{k}x^{k},其中ck=i+j=kaibjmod2c_{k}=\sum_{i + j=k}a_{i}b_{j}\mod 2

    例如,对于f(x)=x6+x4+x2+x+1f(x)=x^{6}+x^{4}+x^{2}+x + 1(可表示为6 1 0 1 0 1 1 16\ 1\ 0\ 1\ 0\ 1\ 1\ 1)和g(x)=x7+x+1g(x)=x^{7}+x + 1(可表示为7 1 0 0 0 0 0 1 17\ 1\ 0\ 0\ 0\ 0\ 0\ 1\ 1):

    计算f(x)g(x)f(x)g(x)时,根据乘法规则,x6x7=x13x^{6}\cdot x^{7}=x^{13}x6x=x7x^{6}\cdot x = x^{7}x4x7=x11x^{4}\cdot x^{7}=x^{11}等。系数相加按照模2加法,即异或操作。如计算某一项xkx^{k}的系数时,找到所有i+j=ki + j = kaibja_{i}b_{j},将它们相加(模2)得到该项系数。

    计算多项式除法和取模:

    h(x)=l=0sdlxlh(x)=\sum_{l = 0}^{s}d_{l}x^{l},计算f(x)g(x)f(x)g(x)除以h(x)h(x)的余数。

    f(x)g(x)f(x)g(x)的最高次项除以h(x)h(x)的最高次项,得到商的一项,然后用f(x)g(x)f(x)g(x)减去商与h(x)h(x)的乘积(同样系数运算为模2),重复这个过程直到f(x)g(x)f(x)g(x)的次数小于h(x)h(x)的次数,此时f(x)g(x)f(x)g(x)就是取模的结果。

    例如,对于$f(x)g(x)=x^{13}+x^{11}+x^{9}+x^{8}+x^{6}+x^{5}+x^{4}+x^{3}+1$和h(x)=x8+x4+x3+x+1h(x)=x^{8}+x^{4}+x^{3}+x + 1

    首先,x13÷x8=x5x^{13}\div x^{8}=x^{5},然后计算$x^{5}(x^{8}+x^{4}+x^{3}+x + 1)=x^{13}+x^{9}+x^{8}+x^{6}+x^{5}$。

    f(x)g(x)f(x)g(x)减去这个结果(模2):$(x^{13}+x^{11}+x^{9}+x^{8}+x^{6}+x^{5}+x^{4}+x^{3}+1)-(x^{13}+x^{9}+x^{8}+x^{6}+x^{5})=x^{11}+x^{4}+x^{3}+1$。

    继续这个过程,直到f(x)g(x)f(x)g(x)的次数小于h(x)h(x)的次数,最终得到x7+x6+1x^{7}+x^{6}+1

    代码实现

    
    #include <iostream>
    using namespace std;
    const int maxN=1024;
    struct H
    {
    	int len;
    	int a[2*maxN];	
    	void scan(){
    		scanf("%d",&len);
    		for(int i=0;i<len;++i)
    			scanf("%d",&a[len-1-i]);
    	}
    	void print(){
    		printf("%d ",len);
    		for(int i=0;i<len;++i)
    			printf("%d ",a[len-1-i]);
    		puts("");
    	}
    	H operator *(const H y)const{
    		H t;
    		t.len=len+y.len;
    		for(int i=0;i<t.len;++i)
    			t.a[i]=0;
    		for(int i=0;i<len;++i)
    			for(int j=0;j<y.len;++j)
    				t.a[i+j]+=a[i]*y.a[j];
    		for(int i=0;i<t.len;++i)
    			t.a[i]%=2;
    		while(t.len>0&&!t.a[t.len-1])
    			--t.len;
    		return t;
    	}
    	H operator +(const H y)const{
    		H t;
    		t.len=max(len,y.len);
    		int i=0;
    		while(i<len&&i<y.len){
    			t.a[i]=a[i]^y.a[i];
    			++i;
    		}
    		while(i<len){
    			t.a[i]=a[i];
    			++i;
    		}
    		while(i<y.len){
    			t.a[i]=y.a[i];
    			++i;
    		}
    		while(t.len>0&&!t.a[t.len-1])
    			--t.len;
    		return t;			
    	}
    	H operator %(const H y)const{
    		H mod,q,two;
    		two.len=2,two.a[0]=0,two.a[1]=1;
    		q.len=len;
    		mod.len=0;
    		for(int i=len-1;i>=0;--i){
    			mod=mod*two;
    			mod.a[0]=a[i];
    			if(mod.len==0)
    				++mod.len; 
    			if(mod.len<y.len)
    				q.a[i]=0;
    			else{
    				q.a[i]=1;
    				for(int j=0;j<mod.len;++j)
    					mod.a[j]=mod.a[j]^y.a[j];
    				while(mod.len>0&&!mod.a[mod.len-1])
    					--mod.len;
    			}		
    		}	
    		return mod;
    	}
    };
    H f,g,h,tmp;
     
    int main()
    {
    	int cases;
    	scanf("%d",&cases);
    	while(cases--){
    		f.scan();
    		g.scan();
    		h.scan();
    		((f*g)%h).print();
    	}
    	return 0;	
    } 
    
    
    
    • 1

    信息

    ID
    61
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    10
    已通过
    1
    上传者