BZOJ5087: polycomp【bitset+分块】

5087: polycomp

【题目描述】

传送门

【题解】

首先, 注意到对于这里的mod 2的多项式的乘法, 我们很容易给出一个
使用bitset的压位的算法.
这样就能把复杂度给除掉一个32. 然而n3/32n^3/32还是比较大.
注意到对于f(g(x))f(g(x)), 我们可以将它每10项每10项分别计算.
预处理一下2102^{10}
关于g(x)g(x)的10次的多项式的结果, 然后复杂度就能达到n32/320n^32/320了, 就能过了.

【代码如下】

#include<cstdio>
#include<bitset>
#include<algorithm>
using namespace std;
const int MAXN=4005;
typedef bitset<MAXN*2> bs;
bs l,f,p,g,G[11],F[1024],h,res;int lg2[1024],nf,ng,nh;
void MOD(bs &ret,int pos){for(int i=pos;i>=nh;i--) if(ret[i]) ret^=h<<(i-nh);}
void Add(bs A,bs B,bs &ret){ret.reset();for(int i=0;i<=nh;i++) if(A[i]) ret^=B<<i;MOD(ret,nh<<1);}
void Init(bs &A,int &L){scanf("%d",&L);for(int i=0,x;i<=L;i++){scanf("%d",&x);if(x) A.set(i);}}
int main(){
	int i,j,END,Z;Init(f,nf);Init(g,ng);Init(h,nh);MOD(g,ng);
	for(i=1,G[0].set(0);i<=10;i++) Add(G[i-1],g,G[i]);
	for(i=2,lg2[1]=0;i<1024;i++) lg2[i]=lg2[i>>1]+1;
	for(F[1].set(0),i=2;i<1024;i++) F[i]=F[i^(1<<lg2[i])]^G[lg2[i]];
	for(Z=0,p.reset(),p.set(0),i=0,END=nf-(nf+1)%10;i<=END;i+=10){
		for(j=i,Z=0;j<i+10;j++) Z|=f[j]<<j-i;
		Add(F[Z],p,res),l^=res,Add(p,G[10],p);
	}
	for(;i<=nf;i++,Add(p,g,p)) if(f[i]) l^=p;
	for(MOD(l,nh);!l[nh]&&nh;nh--);
	for(printf("%d",nh),i=0;i<=nh;i++) printf(" %d",l.test(i));putchar('\n');
	return 0;
}
posted @ 2019-03-11 07:25  XSamsara  阅读(246)  评论(0编辑  收藏  举报