子集运算学习笔记
高维前缀和
大概就是对每一维做一遍前缀和
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;
}