首页 > 其他分享 >2.基础优化技巧

2.基础优化技巧

时间:2024-08-23 18:15:26浏览次数:10  
标签:偏序 二分 技巧 复杂度 分治 基础 区间 例题 优化

基础优化技巧1

三分

一般仍然是用二分+eps处理。

01分数规划

求解形如:

有 \(n\) 个物品,每个物品有两个权值 \(a,b\),选出一些物品,使得两个权值和的比值最大或最小。也就是另 \(w_i=0/1\),最大化:

\[\frac{\sum w_i\times a_i}{\sum w_i\times b_i} \]

一般我们用二分答案处理,移项可得:

\[\sum w_i(a_i-t\times b_i)\ge 0 \]

例题1- [HNOI2009] 最小圈

给定有向带权图,在图上找一个环,使得环上边权和除以节点个数最小,求这个最小的平均值。

\(n\le 3000,m\le 1000,w_i\le 10^7\)。

观察到答案是比例形式,联想到 \(0/1\) 分数规划。考虑把边看作 \(a\),点看作 \(b\),二分一个答案后,边权 \(v\) 重新赋值为 \(v-t\),使用 SPFA 找负环即可。找到负环说明 \(mid\) 仍能再小。

判负环注意是入队次数大于等于 \(n\)。

写完才发现远古题的恶心之处:

  • 复杂度正确的 BFS SPFA过不了,复杂度错误的 DFS SPFA能过?
  • 题解所有人的算法最差复杂度达到 \(O(m^2n\log )\),这也能过?
  • 4202年还需要洛谷机子加强到 5s,9002年的科技就是发达,1s跑3e9。

整体二分

建议改名整体分治。注意复杂度分析。

例题2- P3527 [POI2011] MET-Meteors

有一个初始为 \(0\) 的序列 \(a\) 和 \(m\) 个操作,每个操作是区间 \([l_j,r_j]\) 加 \(k_j\)。你要对于每个位置 \(i\),求出第几次操作后能使得 \(a_i>x_i\)。

\(n\le 3\times 10^5\)。

可以主席树二分做,但是空间被卡了。

如果只有一个国家是简单的,直接二分时间+前缀和即可。

考虑对所有国家同时进行二分, 函数 solve(l,r,<vector>v) 表示时间(操作数)的范围是 \([l,r]\),序列是 \(v\)。

每次二分一个 mid=l+r>>1,执行 \([1,mid]\) 时间内的操作,看每个点是否超过限制 \(x_i\)。超过则说明需要小一点,放在 \(v_l\) 里,否则放在 \(v_r\) 里。注意树状数组及时清空即可。

以上是常见错误,复杂度退化成单个二分。

实际上整体二分是分治,不知道谁起的这个名字。分治过程中复杂度只能与分治区间有关。树状数组需要通过撤销清空。

复杂度 \(O(n\log^2n)\)。

怎么这题还卡 long long

void solve(int l,int r,vector<int>v) {
	int mid=l+r>>1;
	if(l==r) {
		for(int x:v) ans[x]=l;
		return ;
	}
	vector<int>v1,v2;
	for(int i=l;i<=mid;i++) {
		if(op[i].l<=op[i].r)
		t.update(op[i].l,op[i].r,op[i].k);
		else t.update(1,op[i].r,op[i].k),t.update(op[i].l,m,op[i].k); //
	}
	for(int x:v) {
		int tmp=Query(x);
		if(tmp<lim[x]) lim[x]-=tmp,v2.push_back(x);
		else v1.push_back(x);
	}
	for(int i=l;i<=mid;i++) {
		if(op[i].l<=op[i].r)
		t.update(op[i].l,op[i].r,-op[i].k);
		else t.update(1,op[i].r,-op[i].k),t.update(op[i].l,m,-op[i].k); //
	}
	solve(l,mid,v1);solve(mid+1,r,v2);
}

补充例题 P8231 [AGM 2022 资格赛] 农场

将例题2 搬到矩形上

套用二维树状数组即可。

分治

例题3- 【模板】三维偏序

三维偏序,第一维度直接排序做。

然后分治,处理经过分治中点的区间,第二维度左右区间分别归并排序后双指针,注意这样仍满足第一维度的限制,第三维度双指针的时候用权值树状数组在左区间修改,右区间查询。

注意处理相等元素会很麻烦,所以直接去重就好了。记录一下重复元素个数。

bitset 解决 更高维度的偏序

构造01矩阵 \(S_{p}\) 表示第 \(p\) 维度的偏序关系,不难发现 \(S_1({i,j}) \and S_2(i,j)...\) 即为 \(i,j\) 在所有偏序上的关系。只需用 count() 函数计算 bitset 中 \(1\) 的个数即可。

构造 \(S\) 的过程也比较简单,对于每一维先排序,再用 bitset 记录比自己小的集合即可。

时空复杂度 \(O(n^2/\omega),\omega=64\),时间上常数较小,空间上比较紧:**牢记NFLS bitset 惨案:1个长度为 \(N\) 的 bitset 内存是 \(N\times 4/\omega,\omega=32\) **。当 \(N=10^{10}\) 时达到了 1G+,小心MLE保龄。

补充例题 :P3769 [CH弱省胡策R2] TATT

四维偏序

补充例题:P5979 [PA2014] Druzyny

例题4:分治与最短路 - P3350 [ZJOI2016] 旅行者

给你一个 \(N\times M\) 的网格图,边有正边权,\(Q\) 次询问,从 \((x_0,y_0)\to (x_1,y_1)\) 的最短距离。\(N\times M\le 10^4,Q\le 10^5\)。

好题!二维题分治一维。

我们知道长成最短路的通常只能用最短路算法(网格图虽说可以 \(dp\),但显然不好做),我们曾做过:[GXOI/GZOI2019] 旅行者,使用二进制分组的方式建虚拟源点跑 \(\log\) 次最短路。那么这道题能否用类似的方式呢?

观察到 \(N\times M\le 10^4\),\(\text{CandyBar}\) 曾在根号重构中讲过类似的处理套路,即 \(\min(N,M)\le 100\)。

那么就可以枚举较短的那一条边作为虚拟源点了,外面再套个啥?理应想到分治,因为我们能根号对数时间内快速处理跨过一个点的询问点对。用分治进行降维。

复杂度 \(O(n\sqrt n\log n+Q\sqrt n)\)。

例题5:区间最大值分治 - CF1156E Special Segments of Permutation

给定长度为 \(n\) 的排列,求多少区间满足 \(p_l+p_r=\max _{i=l}^r p_i\)。

不要往扫描线上想,这是经典序列分治,直接考虑中点,和前缀后缀最大值即可。比较麻烦。

还有一种不大经典的分治,考虑最大值分治,然后最大值所代表的区间是好确立的,我们 只遍历短的那一边,另一边用数据结构 数组查找。

另外可以往笛卡尔树启发式合并上想。

补充例题:CF1175F The Number of Subpermutations

求满足 \(1...r-l+1\) 各出现一次的区间 \([l,r]\)。

考虑刻画一个满足条件的区间:

  • 区间最大值为 \(r-l+1\)
  • 区间每个数都只出现了一次。

发现这样足以,前者可以区间最大值分治,后者可以用比较套路的方法:记录上一个出现的位置为 \(p_i\),则 \(\max_{i=1}^rp_i<l\)。

注意到区间长度实际上已经确定,因此无论左边右边都直接枚举做即可。

Wa了一次的原因是,枚举左端点,算出右端点,需要保证右端点跨过最大值。

补充例题1:P5979 [PA2014] Druzyny

倍增

常见应用:

  • Floyd 判圈
  • 求LCA / \(k\) 级祖先
  • ST 表

要求:具有结合律,不要求可减性。

例如:\(O(\log n)\) (查询)求树上路径 \(\min,\gcd\)。

其正确性由 二进制表示的唯一存在性给出。

例题6:国旗计划

环上给定 \(n\) 个没有包含关系的区间 \([l_i,r_i]\),求必须选第 \(i\) 个区间的情况下,还需要选多少区间才能使得 \([1,n]\) 全部被覆盖。

首先断环为链,对于本题,要么处理区间,要么处理位置。

处理区间的话,我们有显然的贪心策略:如果按右端点排序,跳到最后一个左端点小于当前区间右端点的区间。这个可以简单预处理得到。

然后需要从一个区间不断跳,直到跳到这个区间左端点右边,我们有 \(O(n^2)\) 的模拟,可以倍增优化这个过程。

哈希

通过把某个对象通过对其特征的描述映射为一个值来去重/判断相等。

关键在于抽象其关键信息,以构造适当的哈希函数。

字符串哈希

把字符串看作 B (B>26) 进制数,随机选择一个大质数 \(P\)。结论是两个随机字符串的哈希值相同的概率大约是 \(\frac{1}{P}\)。所以当比较次数较大的时候使用双模哈希。但打CF的时候小心被人对着卡。

自然溢出容易撞的原因是:如果哈希函数构造不当导致很多偶数乘进来,例如结果为一个 \(2^{100}\cdot d\),自然溢出的结果为 \(0\)。

例题7 异或哈希:[ABC250E] Prefix Equality

给定两个序列 \(A,B\),多次询问,每次给出 \(x,y\),判断 \(A\) 的前 \(x\) 项和 \(B\) 的前 \(y\) 项构成的集合是否相同。(集合不可重)

显然是和顺序无关的函数,而且我们只在第一次出现的地方修改哈希即可。

常见的套路就是每个值随一个大数,异或起来。

如果拓展到区间,放到主席树上就ok了。

Trie

例题8:P3065 [USACO12DEC] First! G

给定若干字符串,你可以任意规定字符间的偏序关系,求有多少字符串能够成为字典序最小的字符串。

首先只有作为前缀的字符串才有可能是答案。

建出 trie 树,一个串能成为答案,那么从根到这个节点,会形成若干偏序关系,我们需要判断这个偏序关系是否合法。

后者是经典图论模型,偏序关系连边后判断是否成环即可。可以用拓扑排序。

例题9:P4551 最长异或路径

给定一棵树,边有边权,求两点间路径异或和最大是多少。

树上路径异或直接前缀和,甚至不需要求 lca。

问题转换为 \(n\) 个数两两异或和最大是多少。都插到 01trie 里,查询的时候尽可能反着走就行。

注意全局加一是从小往大插,其它都是从大往小插。

例题10:CF888G Xor-MST

有一张 \(n\) 个点的完全图,边权为 \(a_i\oplus a_j\),求MST。

妙妙题。

实际上是 B开头的 MST 算法,考虑初始有 \(n\) 个连通块,每次寻找所有连通块连出去的最小边,将这些边加入最小生成树,并合并这些连通块。

每次连通块个数至少减半,所以复杂度是 \(O(m\log n)\)。

对于这个题,我们建出 01trie 后,如何找最小边?这两个点的 lca 一定尽可能深,所以 dfs 一遍tire,从下往上,找到一条最小的边,合并每个点的左右子树。根据 B-算法,这样做是正确的。不需要 dsu 等其他东西。

如何找到最小的边?可以遍历较小的一棵子树,在另一棵子树查询,复杂度类似启发式合并。

也可将原数组排序后再建树,这样树上每个点都对应原数组一段区间。直接遍历即可,每个点只会被其祖先访问,01trie深度是对数级别的。总复杂度 \(O(n\log^2n )\)。

标签:偏序,二分,技巧,复杂度,分治,基础,区间,例题,优化
From: https://www.cnblogs.com/AK-IOI/p/18376806

相关文章

  • 财务报表分析技巧:重点指标解读与实用建议
    一、概述财务报表包含了大量信息,但在分析时,如果没有清晰的思路或忽略了重点,很容易陷入数据的迷雾中。本文将详细介绍财务报表中的几个核心指标,包括如何分析资产负债率、解读净资产收益率以及计算销售复合增长率,以帮助大家有针对性地理解这些内容。二、关键指标解读首先,我们需......
  • 命令拼接技巧
    现在由于IP没有做任何过滤,因此可以进行命令拼接,但是进行命令拼接还要分为不同的操作系统|操作系统|符号|示例|说明||----------|-------|--------------------|----------------------------------------......
  • 感染 点分治优化建图
    I国有\(n\)个城市,有\(n-1\)条道路连接,并且所有的城市相互可达。城市因为自身的交通因素,人口因素,有一个传染力\(r_i\),一旦这个城市爆发疫情,会迅速感染其他距离小于等于\(r_i\)的其他城市,并且造成连锁反应。问一开始最少几个受到境外输入,会导致整个国家\(n\)个城市全部......
  • 每天学习一个基础算法之选择排序
    目录前言:一、选择排序的基本思路和实现方法1、基本思路2、实现方法二、选择排序的执行过程示意图三、选择排序的实现代码选择排序代码主体(以接口函数的形式)测试部分(主函数调用) 四、对选择排序复杂度的分析背景知识:1、选择排序的时间复杂度 精确计算:*采用大O......
  • Day06_0.1基础学习MATLAB学习小技巧总结(6)——矩阵运算篇
    利用暑假的时间把碎片化的MATLAB知识重新系统的学习一遍,为了在这个过程中加深印象,也为了能够有所足迹,我会把自己的学习总结发在专栏中,以便学习交流。素材来源“数学建模清风”特此说明:本博客的内容只在于总结在使用matlab中的一些小技巧,并非教程,若想系统的学习MATLAB,也可以移......
  • Platform - AWS基础初识
    前言什么是云?借助云计算将基础设施视为视为软件并使用,具备可编程资源、动态伸缩能力、随用随付的优势。传统方式:通过公司网络访问和管理本地部署的服务器、存储、数据库、应用程序等软硬件资源云计算:通过互联网使用和管理云服务提供商的存储、服务器、数据库、应用程序等云......
  • 基础组件:表单
    实际业务中,在正式向服务器提交数据前,都会对各个输入框数据进行合法性校验,但是对每一个TextField都分别进行校验将会是一件很麻烦的事。还有,如果用户想清除一组TextField的内容,除了一个一个清除有没有什么更好的办法呢?为此,Flutter提供了一个Form组件,它可以对输入框进行分组,然后进......
  • OI基础操作
    ----------------------------------IO------------------------------Directory.Exists(path)//判断文件夹是否存在------------------------------------------------------------------Directory.CreateDirectory(path)//根据路径创建出文件夹------------------------......
  • 基础组件:ICON
    Flutter中,可以像Web开发一样使用iconfont,iconfont即“字体图标”,它是将图标做成字体文件,然后通过指定不同的字符而显示不同的图片。在字体文件中,每一个字符都对应一个位码,而每一个位码对应一个显示字形,不同的字体就是指字形不同,即字符对应的字形是不同的。而在iconfont中,只......
  • 基础组件:单选开关和复选框
    一、简介Material组件库中提供了Material风格的单选开关Switch和复选框Checkbox,虽然它们都是继承自StatefulWidget,但它们本身不会保存当前选中状态,选中状态都是由父组件来管理的。当Switch或Checkbox被点击时,会触发它们的onChanged回调,我们可以在此回调中处理选中状态改变逻辑......