数据结构与她的爱恨情仇

不会KDT啊/kel

我永远喜欢数据结构!(太违心了吧)

HH的项链

又是区间颜色数,求出每个位置的pre,然后二维数点就行了

区间加区间sin和

和差角公式
sin(x+y)=sinxcosy+sinycosx
cos(x+y)=cosxcosy-sinxsiny
来回维护就行了(过了这题的后一天数学考试有道题要求sin值,我直接套公式233

文文的摄影布置

考虑对每个区间维护A,B,AB,BC,ABC就能区间合并信息啦

脑洞治疗仪

线段树二分就行啦,其他的都很平凡

维护数列

卡空间序列平衡树/ll

火星人

平衡树维护区间hash

LOG

性质:考虑将>s和<=s的分开考虑,对于<=s的部分只要他们的和满足就行了,证明可以考虑不断删大的,接下来就是平凡的权值平衡树了

算术天才⑨与等差数列

判断等差数列,直接维护平方和,类似hash一样判断就行了

楼房重建

由于这一类问题求的是前缀最大,通过这个优美的性质,虽然不能在O(1)的时间内合并信息,但可以在log时间内合并区间信息!

y-fast trie

考虑维护x+y<c的部分
我们维护x的最优匹配是y且y的最优匹配是x的数对,这样的数对最多n个
于是用multiset维护数集和答案集合就行了

考虑对于每个位置,找出一个pre使得pre上的值和这个和为w,再优化一下,如果pre<pre相同值,就将pre变成0,又是n个对子了
于是用set维护再跑个线段树查max(pre)

相逢是问候

扩展欧拉定理(上帝)+分块求快速幂+线段树

括号修复

先来处理最小操作次数:最后的序列一定变成)))(((,于是(为+1,)为-1,则答案变成了pre/2+suf/2上取整
接下来好好处理下标记就平凡了,优先级:覆盖,翻转,取反,考虑不同标记影响即可

动态逆序对

按时间建立三维空间,就成了三维偏序了

CF1039D You Are Given a Tree

考虑n^2暴力对于每个k用贪心满足最优子结构dp转移就行了
考虑根号分治
对于k<=n的暴力
对于k>n的,答案至多有n种,像整除分块一样,只是判断结束端点时要二分,复杂度nnlogn

21/12/16:补题(口胡

YY题

给定一个序列,序列上的每个值都是一个矩阵
区间修改为同一个矩阵
区间查询从左到右的矩阵乘积
要求1log

普通线段树是log^2,因为push_down带一个log
考虑将序列扩展成2^k的形式,后面填0即可
这样我们每个节点存下A^0, A^2, A^4....类似于ksm
push_down时就直接查表就行了,每次修改的复杂度就进化了

CF453E Little Pony and Lord Tirek

颜色段均摊
ti=miri,按照ti建权值主席树(当然也可以是线段树)
于是问题就变成了二维数点了

P5610 大学

考虑存下每个倍数的下表,暴力修改,因为d(5e5)<=168
然后你甚至可以写168个平衡树?当然也可以直接vector

CF438D

取模至少会减半,所以维护区间max就行了

CF702F T-Shirts

考虑按人数建平衡树,将T恤的q从大到小排序,一个一个插入,对剩余钱数的影响
考虑分裂平衡树上>=c的值,好像不能直接打标记?
没关系,考虑对[c,2c]暴力删除插入,对于剩下的点就可以达标记了/cy
每个数会被减半,log^2

HDU 6315 Naive Operations

给两个序列a和b,b是1-n的排列
1.a区间加1
2.求区间内所有[ai/bi]的和

终于有可做题了
由于调和级数,答案的增量一定小于nlogn
于是每个点均摊下来最多被修改log次
如果一个点的a+1后答案会+1,暴力修改,维护一下区间min就可以做到了(CSP2021T1

P5506 人人本着正义之名

考虑维护区间0/1段,修改就变成了0段长度+1/-1,1段长度+1/-1;
于是维护一大堆东西即可
但这题还有最关键的一点,可能会把一个连续段给删除
这时候可能需要维护最小段长度值,为0暴力删去
每次修改只会增加O(1)个段,修改一个是log的
总复杂度log

CF1446D2

有一个性质,区间出现次数最大的一定有一个是全局众数
于是我们确定了a这个值,再枚举个b的值,只需要再O(|b|log)时间内完成就行了
考虑将a,b的位置标记在序列上,考虑和括号匹配一样,将每个b在a上的pre和suf标记出来(不同b的presuf可重的话,需要前移/后移),于是将未被标记的a删掉,简单证一下可得未被标记这个点包含这个点的所有区间都不符合条件,于是有用的值得个数就成了长度个,考虑将a,b当成括号做一遍前缀和,枚举x找到最大的i使得f[i]=x最小的j使得f[j]=x这个题就做完了

P4062 Yazid的新生舞会

考虑和上一个题同一个做法,对于x=[1,n],标记出x的位置,未被标记的点一定不合法
然后求个前缀和放树状数组上查就行了

好像可持久化必须要满足可以差分啊,还有增量要小啊

P4592 异或

都是查询诶
1查询直接记录dfs序转化为区间维护01trie即可
2直接树上差分,维护根到每个节点的可持久化trie即可,分段求即可

ans[x->y]=ana[x]-ans[lca]+ans[y]-ans[fa[lca]]

Bzoj2653: middle

中位数处理方式可以考虑二分,将>x标记为1,<=x的标记为-1,于是考虑x的变化过程中只会有很少的值发生变化,可持久化线段树存每个x的1/-1序列即可

CF464E The Classic Problem

可持久化线段树做最短路
线段树二分处理进位+线段树上二分hash比较字典序

P3302 森林

启发式合并,维护从根到节点的主席树即可,当然还得再维护个lca

CF997E Good Subsegments

考虑将坐标建立二维平面,每个点(i,j)的点值为max-min-(r-l),查询就变成了0的个数
然后在单调栈一下进行n个矩形修改,再来n个平凡的矩形处理r-l
于是就可以快乐的扫了,这题有点像典中典了
修改和查询在扫的时候一起进行就行了,当然矩形加的时候我们还需要进行矩形查询,怎么办呢?
我们可以打个标记B,代表历史和,每个时刻对[1,n]都打个标记就行了

UOJ 637. [美团杯2021] A. 数据结构

给一个长为n的序列,m次查询:
如果将一个区间中所有数都+1,那么整个序列有多少个不同的数?
询问间独立,也就是说每次查询后这个修改都会被撤销

考虑每个颜色对那些询问有贡献
考虑不存在x颜色的询问有哪些
1.区间包含所有x
2.区间不包含任何一个x-1
做一个矩形并,矩形个数为n个
n个矩形的面积并复杂度是O(nlog)的

八云蓝自动机 Ⅱ(改)

操作为
1.交换两个数
2.区间染色
3.单点查
多次询问操作区间[l,r]依次操作,3操作的结果的和
1e6

考虑扫l(n->1),为护r的答案
由于区间染色的特性,对于一个x,会贡献到离他近的询问,且无论前面怎么操作都是这个结果
于是维护一个序列,每个点有个vector代表这个位置将会有哪些时刻询问她
对于l-1时刻
1.交换两个vector即可(因为前面最先交换了一下)
2.将区间每个点的vector删除并累加近答案,满足均摊性质
3.push_back

CF765F Souvenirs

数对子
考虑计算有贡献的对子,即
对于一个i,考虑将后面能与i组成有贡献的对子计算出来(类似单调栈的过程)(可以想成是一个区间)
假设栈顶的一个对子为(i,j),分类讨论
1.ak>=aj ak 不优,被(i,j)或(j,k)替代了
2.ak>ai+aj/2 不优,被(j,k)替代了
3.ak<=ai+aj/2 优,没有可替代的,将k加入栈中

值域减半,我们可以主席树来求出这nlog个对子
对于每一个对子,再来个矩形取max即可,由于是2-side矩形,打上标记就完了

对于差的题,我们都可以将值域看成[k,k/2]来考虑,来判断我们的最优解

区间加区间rank

维护一个序列
1.区间加
2.查询区间小于x的数个数

考虑分块,将每个块内排序,修改打标记,查询块内二分
对于零散块修改,归并即可

P3863序列

由于求的是时间信息,查单点,于是考虑直接扫描线扫序列,数据结构维护时间维
然后就是上个题了

HNOI2016大数

灯饰等使等式!!!

考虑一段数=(sufl-sufr+1)=数*10^k

如果一个数是p的倍数,则sufl%p=sufr+1%p

于是小Z的袜子

P3604 美好的每一天

异或也可以前缀和,一个区间的状压值可以通过两个前缀异或得到,所以莫队即可

P5268 [SNOI2017]一个简单的询问

被这一类问题坑了两遍了

首先差分,然后莫队随便做了,把每个x的答案存起来

于是,对于这一类问题我愿称之为hs问题,这类问题需要求的信息需要大力枚举,但是假设用莫队O(1)扩展的话,扩展的这个点对枚举的信息影响很小,并能快速算出这个扩展值得贡献,就可以用看似更暴力的莫队快速解决

BZOJ4358

查询一个区间中最长的值域连续段
值域连续段[x,y]即区间中存在[x,y]内所有数
值域连续不意味着序列上连续

维护值域的每个边缘点向另一侧延伸的最远位置,类似链表
写个回滚莫队,修改这个链表即可

probelm

序列a,每次给个x和y
查询最小的|i-j|
使得ai=x,aj=y

按照出现次数根号分治
出现次数>B的预处理即可
出现次数<B暴力归并

probelm

给定一个序列,每次查询给定x,y,k
求出ax+ax+k+ax+2k+...+ay的和,保证k|yx

对于k>B的,暴力
对于k<B的,预处理,枚举每个数再枚举k太差了,我们考虑枚举k再枚举n,于是n个点上的前缀和就被我们存下来了,也可理解这张图上有n条边

SHOI2006 Homework

1 X : 在集合 S 中加入一个X,保证 X 在当前集合中不存在。
2 Y : 在当前的集合中询问所有X mod Y最小的值
X,Y <= 1e5

对于Y<B的,预处理,每加进一个数将每个的答案统计一下
对于Y>B的,端点个数<B,于是就可以先分块,在查

Codechef DGCD

给出一棵n个点点权树,有m次操作:
1、询问一条路径上的GCD,即最大公约数
2、将一段路径上的点权加上d

一段路径gcd可以看成gcd(a1,b2,b3....)
b为差分数组
于是只需要维护差分数组区间gcd,区间加变成单点加

由于gcd由x变为y的复杂度为O(x/y),所以修改均摊是1log的

树链剖分

P5354 [Ynoi2017]由乃的OJ

暴力的话,按位贪心,考虑每个2^k进入一个区间后会变成0还是1
直接存下线段树上每个点的每个k的每个01
这样是3log的
优化
我们将所有k压成一个二进制数,发现区间合并可以用位运算实现,2log

P4211 [LNOI2014]LCA

差分掉,扫描线,问题变成了给定x,求x到一个扫到的前缀的sigmadeplca和
我们考虑把前缀上的每个点到根的路径+1,询问x时候查询x到根的路径和即可

CF757G

给出一棵n个点的树及一个1~n的排列pi,边有边权,有q次操作:
1 l r x 求 ∑i=dis(p_i,x) , l <= i <= r
2 x swap(p_x,p_{x+1}) n,q<=2 * 10^5,强制在线

和上个题一样,再开个主席树即可

YY1

给一棵树,边有边权,求所有链中边权xor和最大的一条链

由于dep[x]^dep[y]=dist(x,y)
所以直接01trie

YY2

给一棵树,点有点权,求所有链中点权xor和最大的一条链

点分治或者dsu on tree都行

loj 6276

树,点有颜色,有多少链满足上面的颜色互不相同
每种颜色出现次数<=20,n<=1e5,4s

补集转换,考虑每个颜色至少出现两次,则对于一个颜色的两个点x,y对于x子树和y子树内的点的路径都不合法,于是我们可以把这些两两之间的点的矩形投到二维平面上,20n个矩形,答案就是个矩形面积并了

P6626消息传递

考虑用点分治进行路径规划,对于一个查询的点x,考虑x所在子树,将以重心为根的其他子树的<=y-z的点个数算出来(z为x到重心距离),于是做一下前缀和就行了,再不断分治x所在子树

P3224 [HNOI2012]永无乡

启发式合并+维护权值splay

P4197 Peaks

kruskal重构树

P4054 [JSOI2009]计数问题

考虑值这一维很特殊,于是我们维护100个二维树状数组,动态修改查询就行了

P4690 [Ynoi2016]镜中的昆虫

单点就比较好做了,树套树即可

可以颜色段均摊,这样的话就只修改n+m次pre就行了

P3242 [HNOI2015]接水果

先只考虑一种情况:lca(x,y)不等于x,y,于是可以转换dfs序变成了一个矩形kth的问题,我们可以将这个矩形的差分矩形的树套树求出来,扫描线的同时可持久化就行了

bonus

如果是查询这个路径包含的路径里面权值kth呢?

正难则反,考虑一个初始路径能贡献给那些询问的路径,就回到弱化版本了,询问变成了单点查矩形kth

于是我们考虑扫描线,每次区间插权值,单点查区间kth,,我们可以用树套树,用到了一个标记永久化的思想,我们区间插值的时候只在log个区间上单点修改,儿子就不管了,这样的话我们可以保证一个叶子到根路径上的权值线段树是不交的,于是我们单点查的时候直接在这log个线段树上二分即可

P5445 [APIO2019] 路灯

我们考虑每次修改对后面时刻的贡献,用set维护极长连续段,每次换路灯的时候就等价于一个矩形上的操作(将两边的连续段合并或分裂),于是问题变成了矩形加,单点查

但矩形加该加什么值?考虑一种特殊的维护方式,我们一个点(x,y)的值为x到y路径上一直亮到最后的值,这样的话合并就将矩形+(m-t),分裂的话就将他们-(m-t)

于是矩形加,单点查就可以用树套树或者CDQ分治做了

Bzoj 3489

给出一个长度为n的序列,给出m个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大。如果找不到这样的数,则直接输出0。
n<=1e5,m<=1e6

考虑维护每个点的presuf,该点的贡献为一个矩形,于问题变成了矩形取max,单点查(这不是2-side矩形了)
于是我们可以维护一个线段树套堆   O(n2log+m1log)

Loj 6145

给出一棵树,每次询问一个点x到编号在[l,r]中的点的距离的最小值

两个点之间暴力求路径距离是个简单问题
考虑点分治,把询问的点在当前连通块找出来,查询的就是其他子树的点到分治中心的最小值,且在[l,r]内,可以用线段树来维护单点修改,区间min

P4149 [IOI2011]Race

模板题,直接点分治即可,开个边的数量最小的桶

CF600E Lomsat gelral

dsu on tree 模板,线段树合并!

可持久化并查集

按秩合并,可持久化fa数组即可

probelmC

给定一棵 n 个节点的树,树根为 1,每个点有一个编号,每条边有一个边权。
定义 dep(x) 表示一个点到根简单路径上边权的和,lca(x,y) 表示 x,y 节点在树上的最近公共祖先。
共 m 组询问,每次询问给出 l,r,求对于所有点编号的二元组 (i,j) 满足 l≤i,j≤r ,有多少种不同的 dep(lca(i,j))。

考虑对于每种颜色分别考虑,将他变成一个求和的问题,对于一个lca,对应(x,y)只可能在她的不同子树中,于是我们考虑把每个(x,y)的贡献算出来,我们可以dsu on tree,求出一个子树的set,合并两个子树的时候考虑另一个子树的点x,找出她编号的pre和suf,该颜色的贡献变成了若干个矩形,对每个颜色求出这些矩形的并,问题就变成了矩形加,单点查了

P3703 [SDOI2017]树点涂色

一种特殊的lct处理的问题
1操作就是access操作,由于颜色段的特殊性质(颜色端均摊),我们发现一个点到根的路径中的颜色数目就是虚边数目,于是我们access(虚变实,实变虚)的时候对子树进行一些修改,2操作可以差分掉,3操作直接区间max就行了

P4172 [WC2006]水管局长

路径最大值最小,求一颗MST即可
删边变成加边,维护MST路径的max

考虑加如一条边(x,y),如果x,y不连通直接link,联通的话考虑在原来的MST上找出(x,y)的路径,cut这条路径的最大值,再link这条边就行了

P2387 [NOI2014]魔法森林

对于这种二元组的题,我们都可以先确定一个值,在根据枚举的这个值来求出另一个值
考虑枚举a,只有<=a的边才有意义,考虑a增大的过程中,会加入一些边,而我们枚举a之后只需要维护b的MST就行了,边数是均摊的

P4230 连环病原体

考虑对每个左端点,维护出一个最近的右端点使得这个区间有环,发现这是个单调的,于是直接lct维护即可

CF1017G The Tree

给定一棵树,维护以下3个操作:
1 x表示如果节点x为白色,则将其染黑。否则对这个节点的所有儿子递归进行相同操作
2 x表示将以节点x为root的子树染白。
3 x表示查询节点x的颜色

发现一个点的颜色只会受祖先操作的影响,于是放到序列考虑,1操作相当于在x点+1,如果存在一段路径[y,x]使得这段路径的和>=路径长度,那么x就被染成黑色了(相当于若干个链可以合并)

2操作先把子树内的值赋为0,但是一个x的祖先可能值还是会延伸到一个深度t,直接将a[x]-=t就行了

CF1109F Sasha and Algorithm of Silence's Sounds

给一个n×m的网格图(n,m<=2000,nm<=2*10^5)每个格子上有个权值fij,保证fij构成一个1~nm的排列。问有多少区间满足这个权值在这个区间内的格子构成的连通块是一棵树。

和上面一个题几乎一样,但还有一个问题,假如它是一个森林怎么办,一颗树必须满足点数-边数=1,一颗森林的话点数-边数=树的个数

于是我们对于每个右端点开一个线段树记录有多少个满足m-(r-l+1)=1就行了

CF150E Freezing with Style

二分中位数,>mid设为1<mid设为-1,问题变成了寻找一条[L,R]的路径,使她>0

显然可以点分治,但假如用线段树一类的log数据结构的话复杂度直接奔到O(nlog3)

考虑优化掉一个log,这里就有一个黑科技了

EX_单调队列(没错,这名字我起的)

考虑bfs一个子树,则可选区间是一个滑动窗口,可以维护一个前面所有子树的数组,每次扫即可

但这样显然不行,假如我第一个处理的子树大小为n,子树个数为n,直接退化n^2

由于子树的处理关系与答案无关,于是将子树的深度从小到大排序,这样的话对于前i个子树,我们只存一个长度为i的数组(因为最大深度为i),这样均摊下来每层复杂度O(n+size),总复杂度O(nlog2)

CF741D

震撼到我了

先说一下我一开始的思路,考虑对每个子树分别求解,枚举一个lca,对每一个点记录到lca的状态,并把这个状态加入桶里,然后每次询问直接查桶就行了,但是这样会出现一个问题:我们求出了重儿子的答桶后难以将
整个桶异或上一个值,于是就有了另一种做法

考虑求出每个点到根的异或值,这个显然可以预处理

于是一段路径直接就被拆成了disu xor disv了,这样就不用对一个桶进行修改了

一开始还想到点分治,不过这是求一个子树的答案就gg了

区间加,区间乘,区间染色,区间翻转,区间xor,区间reverse,区间加等差数列,区间取max,区间min/max/mine/maxn(个数),区间开根,区间除,区间颜色数,区间gcd,区间hash,区间rk,区间kth,区间最大字段和,区间多元组最值,

posted @   hs_wfz_orz  阅读(226)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示