首页 > 其他分享 >子集卷积

子集卷积

时间:2023-03-17 20:57:59浏览次数:27  
标签:ch 卷积 sum int 子集 FWT

一想到我 FWT 的笔记还没写就来写这个东西,我就忍不住笑了

子集卷积是一种定义在集合幂级数上的运算,虽然作者对集合幂级数一窍不通,但我们可以先从位运算的角度来理解一下子集卷积,做题的时候,你可以把这个东西看成状压来处理

给出子集卷积基本形式:

\[h_k=\sum_{i \,and \,j\,=\,0\,,i\,or\,j\,=\,k}f_i g_j \]

这里比起最基本的 FWT 多了一个限制

我们考虑把 and 的限制拆掉,注意到 \(i\,and\,j=0\,\leftrightarrow |i|+|j|=|i \,or\,j|\)

所以柿子变成了这个样子

\[h_k=\sum_{|i|+|j|=|i \,or\,j| ,i\,or\,j\,=\,k}f_i g_j \]

考虑构造占位多项式,对于\(f_{i,j}\),若 \(popcount(j)=i\) ,则 \(f_{i,j}=j\),反之则为 0

考虑推柿子

\[h_{i,k}=\sum_{i_1+i_2=i}\,\sum _{a \,or\,b=k}f_{i_1,a}g_{i_2,b}\\ \,\,\,\,\,\,\,\,\,\,\,=\sum_{i_1+i_2=i}\,f_{i_1} *g_{i_2} \]

很明显后半部分可以进行 FWT

由于我们要进行对 \(i_1\) 和 \(i_2\) 的枚举,所以复杂度是 \(O(n^22^n)\) 的

顺便说一下,这里的序列长度是 \(2^n\)

Luogu 模板题据说卡常,加上了快读和取模优化后在 LOJ 上最慢点 1.2s ,成功排到了第 6 页

#include <iostream>

using namespace std;
const int maxN=(1<<21)+10,mod=1e9+9;
int n,lim;
int A[maxN],B[maxN];
int a[21][maxN],b[21][maxN],c[21][maxN];
int ans[maxN];

inline int read( ) {
    char ch = ' '; int ret = 0;
    while( ch > '9' || ch < '0' ) ch = getchar();
    while( ch >= '0' && ch <= '9' ) ret = ret * 10 + ch - '0' , ch = getchar();
    return ret;
}

inline int add(long long x,long long y){
	long long q=x+y;
	if(q>=mod) q-=mod;
	return (int)q;
}

inline int jm(int x,int y){
	int q=x-y;
	if(q<0) q+=mod;
	return q;
}

void fmt(int *f,int len){
	for(int i=0;i<len;++i)
		for(int j=0;j<(1<<len);++j)
			if((j>>i)&1) f[j]=add(f[j],f[j^(1<<i)]);
}

void ifmt(int *f,int len){
	for(int i=len-1;i>=0;--i)
		for(int j=(1<<len)-1;j>=0;--j) if((j>>i)&1) f[j]=jm(f[j],f[j^(1<<i)]);
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	n=read();lim=(1<<n);
	for(int i=0;i<lim;++i) A[i]=read(),a[__builtin_popcount(i)][i]=A[i];
	for(int i=0;i<lim;++i) B[i]=read(),b[__builtin_popcount(i)][i]=B[i];
	for(int i=0;i<=n;++i) fmt(a[i],n),fmt(b[i],n);
	
	for(int i=0;i<=n;++i){//枚举card
		for(int j=0;j<=i;++j)//枚举两部分中的一部分 
			for(int k=0;k<lim;++k) 
				c[i][k]=add(c[i][k],(1ll*a[j][k]*b[i-j][k]%mod));
		ifmt(c[i],n);
	}
	for(int i=0;i<lim;++i) cout << c[__builtin_popcount(i)][i] << " ";
	cout <<endl;
	
	
	return 0;
} 

标签:ch,卷积,sum,int,子集,FWT
From: https://www.cnblogs.com/Benzenesir/p/17228125.html

相关文章

  • 莫比乌斯反演 & 狄利克雷卷积
    大家好,我不会数学实锤了。文章内容较杂,分章节叙述了的大部分有关内容。为什么把这俩放一起?我不知道。积性函数积性函数:\(\foralla,b\),\(a\perpb\),如果一个函数\(f\)......
  • 何为神经网络卷积层?
    摘要:本文深度讲解了卷积计算的原理,并详细介绍了构成所有卷积网络主干的基本元素,包括卷积层本身、填充和步幅的基本细节、用于在相邻区域汇聚信息的汇聚层,最后给出卷积层和......
  • 算法随想Day37【动态规划】| LC416-分割等和子集
    动态规划五部曲确定dp[i]的含义dp递推公式dp数组如何初始化确认dp数组遍历顺序打印dp数组,主要用于调试LC416.分割等和子集这道题是“背包问题”的应用,但其实不好......
  • 一种子集枚举方式的正确性说明
    一种常见的枚举子集的方法是for(intS=SET;S;S=(S-1)&SET)其中,变量\(\rm{S}\)是所枚举的子集考虑\(\rm{S}\)的二进制展开\[\mathrm{S}=(b_1b_2b_3\cdo......
  • 回溯算法解决排列—组合—子集问题
    回溯算法解决排列—组合—子集问题无论是排列、组合还是子集问题,就是让你从序列nums中以给定规则取若干元素,主要有以下几种变体:元素无重不可复选,即nums中的元素都......
  • 转:卷积神经网络
    自今年七月份以来,一直在实验室负责卷积神经网络(ConvolutionalNeuralNetwork,CNN),期间配置和使用过theano和cuda-convnet、cuda-convnet2。为了增进CNN的理解和使用,特写此博......
  • 力扣---78. 子集
     给你一个整数数组 nums,数组中的元素互不相同。返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。你可以按任意顺序返回解集。 示例1:输入:nums=......
  • 小科技之卷积解决字符串匹配问题
    小科技之卷积解决字符串匹配问题OI中有各种字符串匹配问题,常见的有单模式串匹配、多模式串匹配和子串匹配等,一般可以用KMP、AC自动机、SAM解决。如果涉及到其他形式的单模......
  • 【LeetCode回溯算法#07】子集问题I+II,巩固解题模板并详解回溯算法中的去重问题
    子集力扣题目链接给你一个整数数组nums,数组中的元素互不相同。返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。你可以按任意顺序返回解集。示例1:输......
  • 基于步态能量图和CNN卷积神经网络的人体步态识别matlab仿真
    1.算法描述       步态能量图(GaitEngeryImage,GEI)是步态检测中最非常常用的特征,提取方法简单,也能很好的表现步态的速度,形态等特征。其定义如下:     ......