首页 > 其他分享 >线段树分治&cdq分治&整体二分

线段树分治&cdq分治&整体二分

时间:2024-02-23 22:24:18浏览次数:21  
标签:单点 log 线段 分治 修改 cdq 区间

preface

感觉三种分治算法容易搞混并不容易区分它们使用的场景和题目(虽然有些题目根据性质可以使用多种分治),所以还是要归纳一下

线段树分治

Part1

主要是处理一类带有撤回的问题,也就是一次修改只对一段区间生效(这里的区间指的是时间)

即区间修改,单点查询

流程大致是把区间修改挂在线段树对应的节点,然后便利一边线段树,叶子节点就是单点查询

所以线段树分治需要一个支持插入和撤回的数据结构,如可撤回并查集..

[CF813F]Bipartite Checking

题目大意

给你一个由\(n\)个顶点组成的无向图,最初在图中没有边。

同时给你\(q\)次查询,每次查询时会向图中添加一个无向边或者删除一个无向边

在每次查询之后,检查图是否为二分图

solution

全局修改,单点查询

然后用可持久化并查集搞一下

[CF603E]Pastoral Oddities

题目大意

给定一张 \(n\) 个点的无向图,初始没有边。

依次加入 \(m\) 条带权的边,每次加入后询问是否存在一个边集,满足每个点的度数均为奇数。

若存在,则还需要最小化边集中的最大边权。

solution

全局修改,单点查询

先是一个小tip:要求图的度都为奇数,等价于要求图的连通块大小都为偶数,证明:

必要性:反证,考虑若有一个连通块大小奇数,那么图的总度数为奇数,不成立,证毕

充分性:若有把一个偶数大小连通块变成树,一个点若有奇数个儿子,就断父亲的边,否则就上传,可以发现上传的子树大小为奇数,独立的子树大小为偶数,所以到根节点的度一定为奇数,证毕

然后可以想到一种LCT做法

首先能加边就优,显然因为奇+偶=奇,偶+偶=偶,奇+奇=偶,所以奇数连通块只会减小

我们用类似维护最小瓶颈生成树的方式维护这棵生成树,如果加入一条小于当前答案的边,那就把它加入树中,并断掉最大边,判断合法性。若合法,则继续断边。可以发现这样贪心是优的,类似dij的流程

但是这里是线段分治总结...

我们发现一条边它在树边集中出现的一定是一段连续区间,因为它只能在加入到删除前出现,但是我们并不能找到它结束的位置,于是我们考虑从后往前做,找到一条边最后的出现时间,然后再插入线段树

Part2

当然还有单点修改,区间查询的题

单点修改,区间询问,要求修改独立贡献答案

然后对于单点修改就是类似标记永久化的思想,把根到叶子的全部节点都挂上该修改,所以就不要求可撤回

P4585 [FJOI2015] 火星商店问题

题目大意

有\(n\)家商店,操作使\(s\)号商店在第\(i\)天进一个价值为\(val\)的货物(当日就可以卖掉),询问是给出一个数\(x\),在\([l,r]\)天里\([L,R]\)号商店与\(x\operatorname{xor}val\)的最大值是多少。每个商店都会有个永远的货物。

solution

用上面的方法把修改和查询挂好,然后发现查最大值,满足合并性

然后就等于\(n\log n\)去掉了时间维,于是就变成可持久化tire,详情见可持久化trie

Part3 猫树分治

只可以处理不带修的问题...

但是询问不用拆成log个,可以\(O(1)\)

具体流程就是对于线段树每一个节点,在mid处维护一个前缀和后缀,然后对于跨立mid的询问就直接计算,否则下传

[CF1100F]Ivan and Burgers

题目大意

给定\(n\)和\(a_{i\dots n}\),有\(q\)个询问:给定\(l,r\),求在\(a_{l\dots r}\)中选取任意个,使得他们的异或和最大。

solution

首先考虑直接线段树维护,但是发现把合并线性基的时间复杂度是\(log^2\)的,配上线段树就是\(log^3\)

所以考虑猫树分治,每次计算答案时只把一个前缀和一个后缀合并

cdq分治

cdq分治是典型的暴力算法,大体流程是分治处理左右区间内部的答案,每次计算跨立左右的答案,

典型例题有三维偏序(原理是用一个log是偏序少一维),还有一些横坐标无序的凸包题(实现凸包合并)

整体二分

整体二分可以处理单次询问要二分\(O(n\log V)\)的带修问题,进行整体二分+一些数据结构维护(一般是BIT),可以做到\(O((n+q)\log V\log n)\)

具体流程是二分值域,然后判断答案和修改在哪个区间,然后放进对应区间,然后向下做

由于放进右区间的询问要减去左区间的影响,所以要求有可减性

标签:单点,log,线段,分治,修改,cdq,区间
From: https://www.cnblogs.com/zhy114514/p/18028188

相关文章

  • 线段树乱搞大法
    线段树乱搞大法Part1普通线段树简单的区间或单点问题,支持四则运算(可以扩展成可合并的信息,如hash)权值线段树每个节点维护值域为\([l,r]\)的个数,可以维护全局第k大(线段树二分),zkw线段树...Part2懒标记区间操作,历史版本最值/和标记永久化区间操作,单点修改要求:操作顺序不......
  • UOJ228/HDU5828 基础数据结构练习题/Rikka with Sequence 题解(势能线段树)
    势能线段树。如果线段树上一个节点的\(\max-\min\ge2\),我们称其为关键节点,考虑定义势能\(\phi\)为线段树上关键节点的个数。对于每次开方操作,如果当前节点为关键节点,则暴力递归左右儿子修改,否则:如果当前节点\(\max=\min\)或\(\max=\min+1\)且\(\max\)不是完全平方数,......
  • 山海经(线段树)题解
    原题链接:COGS775题目描述:“南山之首曰鹊山。其首曰招摇之山,临于西海之上,多桂,多金玉。有草焉,其状如韭而青华,其名曰祝余,食之不饥……又东三百里,曰堂庭之山,多棪木,多白猿,多水玉,多黄金。又东三百八十里,曰猨翼之山,其中多怪兽,水多怪鱼,多白玉,多蝮虫,多怪蛇,名怪木,不可以上。……”(其实就......
  • 线段树模板
    向上回溯voidpushup(intrt){ t[rt].sum+=t[lc].sum+t[rc].sum; t[rt].mx=max(t[lc].mx,t[rc].mx);}建树voidbuild(intrt,intl,intr){ t[rt].l=l; t[rt].r=r; if(l==r){ t[rt].mx=t[rt].sum=a[l]; return; } intmid=(l+r)>>1......
  • 洛谷题单指南-贪心-P1803 凌乱的yyy / 线段覆盖
    原题链接:https://www.luogu.com.cn/problem/P1803题意解读:通过某种贪心策略,使得能参加的比赛数越多越好。解题思路:将比赛按照结束时间由小到大哦排序,贪心策略是优先选择结束时间早的比赛,因为这样能保证后面参加更多其他比赛100分代码:#include<bits/stdc++.h>usingnamespa......
  • #根号分治,分块,dfs序#洛谷 7710 [Ynoi2077] stdmxeypz
    题目传送门分析首先把距离变成深度,用dfs序转成区间问题,考虑分块,散块直接改问题是整块,如果模数比较大,可以以深度为第一维下标差分标记,这样查询时就可以前缀和知道答案如果模数比较小,那么给该块打标记,查询时枚举模数即可,然后块长取1000,模数阈值取300,就能尽量减少时间代码#in......
  • 山海经&&Atcoder Alternating String (线段树)
    前言:为什么把他们放在一起?因为我发现把pushup向上回溯放结构体类型函数里比较方便并且这两题确实也有相同思想山海经这题分三种情况左子树前缀和+右子树前缀和2.右子树后缀和与右总区间+左子树3.左区间最大子段与右区间最大子段与左后缀与右前缀特别要注意......
  • #根号分治,分块#洛谷 5309 [Ynoi2011] 初始化
    题目传送门分析如果\(x\)比较大那么可以暴力修改,\(x\)比较小的话可以用数组打标记查询的时候对于暴力修改的部分可以分块,暴力修改的同时需要给块打标记如果\(x\)比较小的情况,一段区间相当于是中间很多段周期加上前后缀(当然可以直接区间减但是我被卡常了)我调的块长是160......
  • 线段树学习笔记
    目录线段树的基础知识什么是线段树线段树的基本操作线段树的建树线段树的单点修改线段树的区间查询线段树的区间修改模板动态开点一些例题TheChildandSequence解法分析CodeLegacy相关知识:线段树优化建图解法分析Code线段树的基础知识什么是线段树线段树是一种分治思想的二叉......
  • 小清新线段树
    小清新线段树定义结合时间复杂度分析(势能分析)以及懒标记应用的非传统线段树可以理解为带剪枝的线段树复杂度证明以TheChildandSequence为例,先看操作1,2,对于一个数\(x\)进行取模,要么这个数保持不变。若模数\(M>\frac{x}{2}\),则剩余部分小于\(\frac{x}{2}\);若模数\(......