子集运算学习笔记

高维前缀和

大概就是对每一维做一遍前缀和

int main()
{
	int n=read();
	for(int i=0;i<1<<n;i++)f[i]=read();
	
	//子集和 
	for(int i=0;i<n;i++)
	for(int s=0;s<(1<<n);s++)
	if(1<<i&s)f[s]+=f[s^(1<<i)];
	
	//子集和逆变换 
	for(int i=0;i<n;i++)
	for(int s=0;s<(1<<n);s++)
	if(1<<i&s)f[s]-=f[s^(1<<i)];
	
	//超集和 
	for(int i=0;i<n;i++)
	for(int s=0;s<(1<<n);s++)
	if(!(1<<i&s))f[s]+=f[s^(1<<i)];
	
	//超集和逆变换 
	for(int i=0;i<n;i++)
	for(int s=0;s<(1<<n);s++)
	if(!(1<<i&s))f[s]-=f[s^(1<<i)];
	
	//补集和考虑翻转数组即可
	for(int s=0;s<(1<<n-1);s++)swap(f[s],f[(1<<n)^s]) 
	return 0;
}

FMT

posted @ 2020-12-07 22:18  Creed-qwq  阅读(115)  评论(0编辑  收藏  举报