高维前缀和学习笔记

高维前缀和,也称 SOSDP。
首先考虑一维的前缀和怎么做。
sumi=sumi1+ai
再考虑二维,我们常用的是根据容斥来写的:
sumi,j=sumi,j1+sumi1,jsumi1,j1+ai,j
当然,还可以这么写。

for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++)
		a[i][j]+=a[i-1][j];
for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++)
		a[i][j]+=a[i][j-1];

继续考虑三维。

for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++)
		for (int k=1;k<=n;k++)
			a[i][j][k]+=a[i-1][j][k];
for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++)
		for (int k=1;k<=n;k++)
			a[i][j][k]+=a[i][j-1][k];
for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++)
		for (int k=1;k<=n;k++)
			a[i][j][k]+=a[i][j][k-1];

但到了 n 维,这样做的时间复杂度是 nn。显然是不够优的。
高维前缀和应运而生。
我们考虑将每个维度压成一个二进制位。
那么当一位为 1 时,就要从 0 转移过来。
核心代码:

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

例题

AT4168 [ARC100C] Or Plus Max

我们可以将问题转化为求出最大的 ai+aj 满足 i or jk
那么我们对于每个 k 求出其子集的最大值和次大值,然后答案即为前缀 max

Code

//LYC_music yyds!
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0)
#define lowbit(x) (x&(-x))
#define int long long
using namespace std;
int read()
{
	int pos=1,num=0;
	char ch=getchar();
	while (!isdigit(ch))
	{
		if (ch=='-') pos=-1;
		ch=getchar();
	}
	while (isdigit(ch))
	{
		num=num*10+(int)(ch-'0');
		ch=getchar();
	}
	return pos*num;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		write(-x);
		return;
	}
	if (x>=10) write(x/10);
	putchar(x%10+'0');
}
void writesp(int x)
{
	write(x);
	putchar(' ');
}
void writeln(int x)
{
	write(x);
	putchar('\n');
}
const int N=(1<<20)-1;
int n,ans;
pair<int,int> a[N];
pair<int,int> merge(pair<int,int> x,pair<int,int> y)
{
	if (x.first<y.first) swap(x,y);
	pair<int,int> res=x;
	if (y.first>res.second) res.second=y.first;
	return res;
}
signed main()
{
	n=read();
	for (int i=0;i<1<<n;i++)
		a[i]=make_pair(read(),-0x3f3f3f3f3f3f3f3f);
	for (int j=0;j<n;j++)
		for (int i=0;i<1<<n;i++)
			if (i&(1<<j)) a[i]=merge(a[i],a[i^(1<<j)]);
	for (int i=1;i<1<<n;i++)
	{
		ans=max(ans,a[i].first+a[i].second);
		writeln(ans);
	}
}
posted @   dd_d  阅读(109)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示
主题色彩