首页 > 其他分享 >高维前缀和乱讲

高维前缀和乱讲

时间:2024-07-28 10:42:48浏览次数:10  
标签:乱讲 前缀 复杂度 枚举 子集 sum 高维

OI-Wiki 看不懂啊,学了一上午。

常见的二维前缀和求法多为容斥原理,虽然这样的计算相对直观且便于记忆,但是当维数往上升高时其复杂度会大大提高,对于更高维度的前缀和可以使用 “高维前缀和” 这一方法,本质上是基于 DP 的。

首先我们可以了解一种一般的优化,我们先对每一 “行” 求前缀和,再累积他们的前缀和;然后对每一 “列” 求前缀和,再累积他们的前缀和……其实就是对于 每个维度分别求和

显然对于 \(t \leq 3\) 这样子的优化是不明显的,但是在 OI 中,如果我们把 \(n\) 位二进制数看成一个有着 \(n\) 维度的坐标,比如 \((111001)_2\) 看作 \(s_{1, 0, 1, 0, 1}\),此时这种优化的优势就非常明显了。

高维前缀和一般可以解决这种问题

对于所有的 \(i\),\(0 \leq i \leq 2^{n} - 1\),求 \(\sum_{j \subset i} a_j(\subset\text{ means subset})\)

考虑直接以朴素的复杂度子集枚举做。

对于子集枚举我们有着大家都知道的 \(O(3^n)\) 的做法:

常见的枚举子集代码是这样的:

for (int s = u; s; s = (s - 1) & u) {
	// s is a subset of u (not empty)
}

单次地枚举子集 \(S\) 的复杂度显然是 \(2^{|S|}\) 的。

那么每次大小为 \(n\) 的子集的复杂度就是

\[O(\sum_{S \in U} 2^{|T|}) \]

\(S\) 中大小为 \(z\) 的子集个数是 \(C_z^n\) 的,然后考虑枚举 \(z\),改写复杂度式子:

\[O(\sum_{i = 1}^n \binom{n}{i}2^i) \]

二项式定理化简:

\[\sum_{i = 1}^n \binom{n}{i} 2^i = \sum_{i = 1}^n \binom{n}{i} 2^i 1^{n - i} = (1 + 2)^n - 1 \]

那么整个的复杂度就是 \(O(3^n)\) 的。\(\blacksquare\)

回到正题,施展高维前缀和,复杂度降到 \(O(n \cdot 2^n)\),代码如下:

for (int j = 0; j < n; j++)
	for (int i = 0; i < (1 << n); i++)
		if (i >> j & 1)
			f[i] += f[i ^ (1 << j)]

我们可以这么理解:

本质上和 for 去跑一维维统计是一样的,具体地讲,我们是正序枚举的,所以 \(i \oplus (1 << j)\) 在当前层,而 \(i\) 还在上一层,然后将两者进行合并不就是上述当前层的前缀和吗?

Bonus(口胡): 对于高维差分,只需要把加号变成减号;对于高维后缀和,求法相同,把所有东西取补集。

似乎这个东西也叫做 SOS DP(Sum Over Subset Dynamic Programming)

标签:乱讲,前缀,复杂度,枚举,子集,sum,高维
From: https://www.cnblogs.com/Yuics/p/18327946

相关文章

  • Vcpkg + cmake + pybind 问题“无法找到平台独立库 <前缀>”
    我发现了vcpkgerlier,它看起来很有趣,但是易于使用。据我了解,经过一天的调查,vcpkgpybind11与vcpkgpython搭配使用。但是当我启动一个简单的程序时,它被中止并出现以下输出无法找到平台独立库<前缀>这是一个已知问题,但不适用于vcpkgpython。我不知道为什么?不......
  • 前缀和与差分
    前缀和与差分前缀和定义:前缀和可以简单理解为「数列的前n项的和」,是一种重要的预处理方式,能大大降低查询的时间复杂度。一维前缀和模板for(inti=1;i<=n;i++)sum[i]=sum[i-1]+a[i];时间复杂度:O(n)原理数组sum用于储存前i个元素的和,数组a......
  • 易优CMS模板标签SQL数据查询查询数据表ey_arctype,指定栏目ID的基本信息,不使用数据缓存
    【基础用法】标签:sql描述:用于获取MySQL数据库内容的标签。用法:{eyou:sqlsql=''cachetime='3600'empty='没有数据'}{$field.数据表相应的字段名称}{/eyou:sql}属性:sql=''需要查询的SQL语句cachetime='3600'数据缓存时间,默认缓存25小时,即86400秒empty=''没有数据时显示......
  • 洛谷题单指南-前缀和差分与离散化-P3397 地毯
    原题链接:https://www.luogu.com.cn/problem/P3397题意解读:给定一个n*n的矩阵,每个元素初始值为0,再将m个子矩阵中的元素都增加1,统计每个元素最终的值。解题思路:1、暴力法枚举每一个子矩阵,将对应元素值加1,时间复杂度为1000^3,不可行。2、二维差分对于给定二维数组s[][],给指定区......
  • 洛谷题单指南-前缀和差分与离散化-P2367 语文成绩
    原题链接:https://www.luogu.com.cn/problem/P2367题意解读:对于数组s[],给指定q个区间[x,y]里每个数增加z,计算操作之后最小的数。解题思路:1、暴力做法对于每一个区间[x,y],枚举给每一个数增加z,然后遍历查找最小值,总体时间复杂度为O(N^2),不可行。2、一维差分对于给指定区间[x,......
  • 洛谷题单指南-前缀和差分与离散化-P1314 [NOIP2011 提高组] 聪明的质监员
    原题链接:https://www.luogu.com.cn/problem/P1314题意解读:计算m个检验值之和,计算与s差值绝对值的最小值。解题思路:1、首先要搞懂检验值是如何计算的如上图,对于每一个区间的检验值yi,表示为:yi="该区间重量>=W的矿石个数" ✖️"该区间>=W的矿石价值之和"检验值y即所有yi(1<=......
  • 洛谷题单指南-前缀和差分与离散化-P8218 【深进1.例1】求区间和
    原题链接:https://www.luogu.com.cn/problem/P8218题意解读:对于数组a[N],给定m个区间l~r,求每个区间所有元素之和。解题思路:先思考暴力做法:对于每一个区间[l,r],累加a[l]~a[r]所有元素,时间复杂度最坏为10^5*10^4,不可行。一维前缀和:设s[N]是a[N]的前缀和数组,即对于每一个s[i......
  • 坐标变化其二 前缀和
    202309-2试题名称:坐标变换(其二)时间限制:2.0s内存限制:512.0MB问题描述:问题描述对于平面直角坐标系上的坐标 (......
  • 前缀和(有意思的求区间值思想)
    第4题   前缀和 查看测评数据信息给一个有一个长度为n的数组a[1,2,...n]。数组a的前缀和定义为s[i]=a[1]+a[2]+...+a[i](对于所有的1<=i<=n),规定s[0]=0数组a的前缀和前缀最大值为max[i]=max(s[0],s[1],s[2],...s[i])(对于所有的0<=i<=n)数组a的1类和谐度为为max[i]中......
  • laravel: 指定redis缓存项的前缀
    一,laravel默认会为缓存项添加前缀:config/database.php中:'redis'=>['client'=>env('REDIS_CLIENT','phpredis'),'options'=>['cluster'=>env('REDIS_CLU......