快速沃尔什变换 FWT

快速沃尔什变换 FWT##


也和FFT很像。
typedef long long ll;
const int P=998244353;
ll _n=ksm(2,P-2);

/*
op=1,2,3分别对应XOR,AND,OR
*/
void FWT(int n,ll a[],int f,int op){
	for(int i=1;i<n;i<<=1){
		for(int j=0;j<n;j+=i<<1){
			for(int k=0;k<i;k++){
				ll x=a[j+k],y=a[j+k+i];
				if(f){
					if(op==1) a[j+k]=(x+y)%P,a[j+k+i]=(x-y+P)%P;
					else if(op==2) a[j+k]=(x+y)%P;
					else a[j+k+i]=(x+y)%P;
				}else{
					if(op==1) a[j+k]=(x+y)*_n%P,a[j+k+i]=(x-y+P)*_n%P;
					else if(op==2) a[j+k]=(x-y+P)%P;
					else a[j+k+i]=(y-x+P)%P;
				}
			}
		}
	}
}


练习##


快速子集变换 FST##

//FWT加上类似背包DP
void FST(int d[],int a[],int n){
	for(int i=1;i<n;i++)
		_[i]=_[i>>1]+(i&1);
	for(int i=0;i<n;i++)
		a1[_[i]][i]=a[i];
	int l=_[n-1];
	for(int i=0;i<=l;i++)
		FWT(a1[i],n,1,3);
	for(int i=l;~i;i--)
		for(int j=0;j<=i;j++)
			for(int k=0;k<n;k++)
				a2[i][k]=(a2[i][k]+(ll)a1[i-j][k]*a1[j][k]%P)%P;
	for(int i=0;i<=l;i++)
		FWT(a2[i],n,0,3);
	for(int i=0;i<n;i++)
		d[i]=(a2[_[i]][i]+P)%P;
}

练习##

  • 【codeforces914G】Sum the Fibonacci
posted @ 2018-07-24 20:16  LSQ647  阅读(164)  评论(0编辑  收藏  举报