首页 > 其他分享 >【学习笔记】高位前缀和(SOSDP)

【学习笔记】高位前缀和(SOSDP)

时间:2024-12-22 22:10:45浏览次数:4  
标签:ch 前缀 int 字符集 笔记 SOSDP 一维 define

高位前缀和解决这样的问题:

给定 \(f_i\),其中 \(i\in[0,2^n-1]\),求解 \(\sum\limits_{j\in i}f_j\)。

考虑一维前缀和:

for(int i=1;i<=n;i++){
	sum[i]=sum[i-1]+a[i];
}

二位前缀和:

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

三维前缀和:

for(int i=1;i<=n;i++){
	for(int j=1;j<=n;j++){
		for(int k=1;k<=n;k++){
			sum[i][j][k]=sum[i][j][k-1]+a[i][j][k];
		}
	}
}
for(int i=1;i<=n;i++){
	for(int j=1;j<=n;j++){
		for(int k=1;k<=n;k++){
			sum[i][j][k]+=sum[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++){
			sum[i][j][k]+=sum[i-1][j][k];
		}
	}
}

可以发现上面那个问题就是每一维大小都为2的 \(n\) 维前缀和。
因此可以考虑枚举每一维,然后再加上这一维的贡献就好了。

for(int i=1;i<=n;i++){
	for(int S=0;S<1<<n;S++){
		if(S>>(i-1)&1){
			continue;
		}
		f[S|1<<(i-1)]+=f[S];
	}
}

Yet Another Substring Reverse
因为字符不重复,因此不用考虑它们的排列顺序,即翻转子串就是将两个不交的子串连到一块。这里不交既指位置不交又指字符集不交。但显然字符集不交则一定位置不交。因此只用考虑对每一个字符集处理最大长度。高位前缀最大值即可。

Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define read(x){\
	char ch;\
	int fu=1;\
	while(!isdigit(ch=getchar()))\
		fu-=(ch=='-')<<1;\
	x=ch&15;\
	while(isdigit(ch=getchar()))\
		x=(x<<1)+(x<<3)+(ch&15);\
	x*=fu;\
}
using namespace std;
namespace asbt{
namespace cplx{bool begin;}
const int maxn=1e6+5,maxm=(1<<20)+5;
int n,dp[maxm];
char s[maxn];
namespace cplx{
	bool end;
	il double usdmem(){return (&begin-&end)/1048576.0;}
}
int main(){
	scanf(" %s",s+1);
	n=strlen(s+1);
	for(int i=1;i<=n;i++){
		for(int j=i,S=0;j;j--){
			if(S>>(s[j]-'a')&1){
				break;
			}
			S|=1<<(s[j]-'a');
			dp[S]=i-j+1;
		}
	}
	for(int i=1;i<=20;i++){
		for(int S=0;S<1<<20;S++){
			if(S>>(i-1)&1){
				continue;
			}
			dp[S|1<<(i-1)]=max(dp[S|1<<(i-1)],dp[S]);
		}
	}
	int ans=0;
	for(int S=1;S<=(1<<20)-2;S++){
		ans=max(ans,dp[S]+dp[((1<<20)-1)^S]);
	}
	printf("%d",ans);
	return 0;
}
}
int main(){return asbt::main();}

标签:ch,前缀,int,字符集,笔记,SOSDP,一维,define
From: https://www.cnblogs.com/zhangxyhp/p/18622618

相关文章

  • 三维测量与建模笔记 - 7.2 点云滤波
        逐点计算法向量,需要对每一个点拟合出它的切平面,一般使用邻域点信息来查找切平面。    选取要计算的点和它周围一定范围内的点可以拟合出一个平面,最基本的方法是通过最小二乘法取对这些点到平面的距离进行优化(计算量很大)。可以通过计算协方差矩阵来实现......
  • 读书笔记:Redis5设计与源码分析
    Redis5设计与源码分析,陈雷本书赞誉序前言第1章引言11.1Redis简介1Redis由SalvatoreSanfilippo在2009年发布初始版本,开源后不断发展壮大。Redis优点:Redis的工作模式为单线程,不需要线程间的同步操作。Redis采用单线程主要因为其瓶颈在内存和带宽上,而不是CPU。1.2Re......
  • 2024/12月 读书笔记 - 7《构建之法》--- 第七章
    微软解决方案框架(MSF)概述本章将探讨微软公司推荐的软件开发方法——微软解决方案框架(MSF),它融合了多种软件开发方法论和原则,旨在指导微软的软件开发实践。MSF的核心原则开放沟通:确保所有信息透明共享,涉及所有相关角色,并公开决策过程。同时,对敏感信息如技术机密和安全性信息采取......
  • 2024/12月 读书笔记 - 8《构建之法》--- 第八章
    在软件开发过程中,准确捕捉和全面理解用户需求是至关重要的。以下是软件团队获取和处理需求的四个关键步骤:获取和引导需求:也称为“需求捕捉”,软件团队需要站在用户的角度思考,引导用户明确他们的需求。分析和定义需求:对收集到的需求进行整理和定义,从不同角度量化需求。验证需求:与......
  • 2024/12月 读书笔记 - 9《构建之法》--- 第九章
    在项目管理领域,不同公司对于项目管理角色的称呼有所不同。以下是几种常见的项目管理角色:ProductManager(PM):产品经理,负责确保产品正确地开发和实现。ProjectManager(PM):项目经理,负责确保项目流程正确地执行。ProgramManager:在微软,这个职位指的是负责特定项目或程序的经理......
  • sentinel学习笔记4-SPI 在 Sentinel 中的应用
    本文属于sentinel学习笔记系列。网上看到吴就业老师的专栏,写的好值得推荐,我整理的有所删减,推荐看原文。https://blog.csdn.net/baidu_28523317/category_10400605.htmljavaSPISPI机制是Java平台提供的一种用于服务发现和服务提供者查找的机制。它允许在运行时动态地加载和......
  • 天嵌通途xczu15eg学习笔记——基于iwip的TCP服务器性能测试(一)
    学习记录——基于iwip的TCP服务器性能测试(一)环境如下,Windows10,vivado2020.2硬件部分设置如下:PS-PL之间的交互时钟,复位已关闭GenerateOutputProducts,CreateHDLWrapper,ExportHardware之后进入vitis开发环境选择IwIPTCPPerfServer模版打开Terminal中的串口编......
  • LeetCode100之实现Trie前缀树(208)--Java
    1.问题描述Trie(发音类似"try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补全和拼写检查。请你实现Trie类:Trie() 初始化前缀树对象。voidinsert(Stringword) 向前缀树中插入字符串 word ......
  • Dart学习笔记:语法
    本文更新于2024-12-22,使用Dart2.18.2。目录关键字常量变量基本数据类型数值字符串布尔列表集合映射运算符运算符优先级算数运算符关系运算符类型判定运算符赋值运算符逻辑运算符位运算符条件运算符访问运算符流程控制条件语句if-elseswitch-case循环语句forfor-inwhiledo-whileb......
  • Golang学习笔记_16——Map
    Golang学习笔记_13——数组Golang学习笔记_14——切片Golang学习笔记_15——range文章目录Map1.介绍2.声明和初始化3.类型4.基本操作4.1插入更新4.2访问值4.3删除4.4遍历5.注意事项6.示例Map1.介绍在Go语言中,map是一种内置的数据结构,用于存储键......