[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3483 [题目大意] 给出一些串,同时给出m对前缀后缀,询问有多少串满足给出的前缀后缀模式, 题目要求强制在线 [题解] 我们对于给出的每个字符串正着插入字典树A,倒着插入字典树B, 对于一个前缀来说,在字典树A上得到的dfs序[st,en]就是所有的匹配串, 同理,后缀在字典树B上dfs序[st,en]表示所有的后缀匹配串, 同时满足两者的需提供二维查询,因此我们以Adfsn为版本,…
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空白叫做A[i-1].data+1, 开头和最尾也要这么插,意义是如果取不了A[i-1]了,最早能取的是啥数.要把这些空白也离散化然后扔主席树里啊. 主席树维护每个数A[i]出现的最晚位置(tree[i].data),查询时查询root[R]的树中最早的data<L的节点(这意味着该节点的下标离散化前代…
[BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义depth[i]为i节点与根节点的距离.为了方便起见,你可以认为树上相邻的两个点之间的距离为1.站在这棵色彩斑斓的树前面,你将面临m个问题. 每个问题包含两个整数x和d,表示询问x子树里且depth不超过depth[x]+d的所有点中出现了多少种…
题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更简单的做法,但是我没有什么想法... 代码 #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #inclu…
BZOJ 考虑没有深度限制,对整棵子树询问怎么做. 对于同种颜色中DFS序相邻的两个点\(u,v\),在\(dfn[u],dfn[v]\)处分别\(+1\),\(dfn[LCA(u,v)]\)处\(-1\),这样答案就是求子树和了(同种颜色多余贡献的会被减掉). 对于深度的限制,考虑维护\(\max\{dep\}\)棵线段树\(T_i\),分别表示只考虑深度在\(1\sim i\)之间的点的贡献(下标依旧是DFS序).因为我们发现,对于询问\((x,k)\),求\(T_{dep[x]+k}\)这…
BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在\([l_i,r_i]\)中的点所有点连\(INF\)边. 但是\(O(n^2)\)条边显然要GG.容易想到用线段树优化. 每次都是向前缀所有的点连边,所以可以离散化后用可持久化线段树连边. 另外其实也不需要拆点,直接连即可. //15336kb 500ms #include <cstdio> #…
题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],rs[N*],val[N*],tot2,a[N],b[N],ql[],qr[],nl,nr; ]; void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;} void df…
题目大意:给定n个字符串,对于每一个字符串求以这个字符串为后缀的字符串中第k小的编号 首先将字符串反转 那么就变成了对于每一个字符串求以这个字符串为前缀的字符串中第k小的编号 然后考虑对字符串排序 那么对于每一个字符串以它为前缀的字符串一定是连续的 那么就转化成了区间第k小 这个用可持久化线段树能够解决 排序自然不能直接排 既然是字符串 考虑Trie树+DFS就可以 注意字符串有反复的 小心 #include <vector> #include <cstdio> #include…
这个思路挺有意思的 ~ 利用树链的并来保证每个颜色只贡献一次,然后用可持久化线段树维护 code: #include <set> #include <cstdio> #include <cstring> #include <algorithm> #define N 100005 #define setIO(s) freopen(s".in","r",stdin) , freopen(s".out",…
如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k大 ,,,, 这个问题的通用算法是 划分树,, 说白一点就是把快速排序的中间结果存起来, 举个栗子 原数列 4 1 8 2 6 9 5 3 7 sorted 1 2 3 4 5 6 7 8 9 ........................... qs[0] 4 1 8 2 6 9 5 3 7 q…
在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth number 题意就不写了,太经典了(可我还是不会这题,我太菜了) 大佬的题解写的太神仙了,我这么菜的人都看懂了2333,所以我就不写了... 不过这题是真的坑啊...老师在上面讲的时候,我们开始提交(他们交主席树,我交整体二分)然后等讲完我们还没过23333 MLE.TLE.WA(可能还有CE)轮…
给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节 点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义depth[i]为i节点与根节点的距离 ,为了方便起见,你可以认为树上相邻的两个点之间的距离为1.站在这棵色彩斑斓的树前面,你将面临m个问题. 每个问题包含两个整数x和d,表示询问x子树里且depth不超过depth[x]+d的所有点中出现了多少种本质不同的颜色 .请写一个程序,快速回答这些询问. 输入 第…
按Dfs序逐个插入点,建立可持久化线段树,每次查询即可,具体详见代码. 不知道为什么,代码慢的要死,, #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> using…
权值线段树 顾名思义,就是以权值为下标建立的线段树. 现在让我们来考虑考虑上面那句话的产生的三个小问题: 1. 如果说权值作为下标了,那这颗线段树里存什么呢? ----- 这颗线段树中, 记录每个值出现的次数 2.权值很大怎么办?数组空间不够啊 ----- 可以先离散化,再记录 3.那权值线段树到底是用来干嘛的呢? ----- 可以快速求出第k小值(其实主要还是为了主席树做铺垫啦) 那第k小值该怎么求呢??? 从树根依次往下 若当前值K大于左儿子的值,则将K-=左儿子的值,然后访问右儿子 若当前…
题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的父亲. 第一种情况很好处理,写法见代码,懒得讲,反正很简单的. 第二种情况的话,按Dfs序建主席树,用主席树维护下标为Dep的序列,每次用Size-1(因为不能取本身:Size[i]即为以i为根的子树节点数)去更新, 询问的时候在以A为根的子树中查找Dep[A]+1~Dep[A]+K的和即可. 不思…
题目链接 对每个结点建立两棵线段树,一棵记录该结点的子树下每种颜色对应的最小深度,另一棵记录子树下的每个深度有多少结点(每种颜色的结点只保留最浅的深度即可),自底而上令父节点继承子结点的线段树,如果合并两棵颜色线段树时发现某种颜色重复,则在深度线段树上把较深的深度对应的位置-1. 注意由于强制在线,深度线段树的合并以及更新都需要可持久化. (ps:不能用map代替颜色线段树,会TLE~~) #include<bits/stdc++.h> using namespace std; typedef…
[BZOJ3439]Kpm的MC密码 Description 背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身份验证问题了... 描述 Kpm当年设下的问题是这样的: 现在定义这么一个概念,如果字符串s是字符串c的一个后缀,那么我们称c是s的一个kpm串. 系统将随机生成n个由a…z组成的字符串,由1…n编号(s1,s2…,sn),然后将它们按序告诉你,接下来会给你n个…
题目:[POI2014]KUR-Couriers 题解: 要求出现次数大于(R-L+1)/2的数,这样的数最多只有一个.我们对序列做主席树,每个节点记录出现的次数和(sum).(这里忽略版本差值问题)对于一个节点,如果左儿子的sum小于等于(R-L+1)/2,则答案不可能在左儿子中:右儿子同理.然后对有可能的儿子递归寻找答案,如果左右儿子都不可能,则不存在答案. 代码: BZOJ 3524: #include<cstdio> #include<cstring> #include&l…
题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y))-ans(father[LCA(X,Y)]) 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; +,maxm=m…
题目: [CQOI2015]任务查询系统 题解: 是一道很经典的题目.大体思路是抓优先级来当下标做主席树,用时刻作为主席树的版本.然而优先级范围到1e7去了,就离散化一遍.然后把每个事件的开始(s).结束(e)(e记得+1,因为一个事件是第e+1时刻结束的)时间点抓出来排序一遍,按时刻从早到晚维护主席树.差不多就是这样. 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algor…
https://www.lydsy.com/JudgeOnline/problem.php?id=3956 从描述可以得到性质: 每个好点对 ( 除了差值为1的好点对 ) 中间的数 ( i , j ) 一定有一个最大值, 视这个值控制这个好点对, 那么每个值最多只控制一个好点对. 然后我们就可以通过单调栈 ( 求出lp[i]左边第一个大于i的数的坐标, rp[i]右边第一个大于i的数的坐标, lf[i]左边第一个大于等于i的数的坐标 (为避免重复只统计有重复区间的值里的最左边一个,即lp=lf则…
Problem Kth Number Solution 裸的主席树,模板题.但是求k大的时候需要非常注意,很多容易写错的地方.卡了好久.写到最后还给我来个卡空间. 具体做法参见主席树论文<可持久化数据结构研究>. AC Code #include "cstdio" #include "iostream" #include "cstring" #include "algorithm" using namespace…
题目背景 SOURCE:NOIP2015-GDZSJNZX(难) 题目描述 学校一年一度的学生艺术节开始啦!在这次的艺术节上总共有 N 个节目,并且总共也有 N 个舞台供大家表演.其中第 i 个节目的表演时间为第 i 个单位时间,表演的舞台为 Ai ,注意可能有多个节目使用同一个舞台.作为 Tom 的忠实粉丝之一的 Alice,当然要来逛一下啦,顺便看一下能不能要到 Tom 的签名. Alice 一开始会先在 A1 看完节目1再去闲逛. Alice 可以在舞台之间随便乱走.但是假如 Alice…
题意:给定一个数组,每次查询第l到r区间的第k大值 解法嘛,当然是主席树,主席树即可持久化线段树,什么叫可持久化呢,就是指能够访问历史版本的数据结构,那么对于某些只能离线处理的题目强制在线之后 ,可以通过在线处理操作 经过这题总算对可持久化线段树有了些了解,我们开始先建一颗空树,然后对于每次修改我们只会修改logn个点,我们可以新建logn个来避免每次都新建一颗线段树导致的爆空间, 对于这题来说我们线段树中维护的是这个区间的点的个数,插入的时候按权值大小插入,对于l到r我们可以通过1-r减去1-…
关键字:线段树 可持久化 线段树:当版本(即对应的原序列的区间[1,r])一定时,每个节点的left,right下标为值域,值为其对应的原序列区间[1,r]中元素大小在值域中的元素个数. 可持久化:新版本(对应原序列[1,r])在旧版本(对应原序列[1,r-1])上建立,从树根向树叶构造,在旧版本的节点的旁边构造新版本的节点,值为旧版本节点值+1.搜索新版本树时,从新版本树根开始搜索即可.求区间第k大,同时遍历[1,l-1]对应版本树和[1,r]对应版本树,通过节点值的差来得到第k个节点. #i…
题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于每个点 i 就要连边 (S, i, B[i]) 和 (i, T, W[i]). 这样,如果一个点属于 S 集,就要割掉与 T 相连的边,就相当于失去了染成白色的收益. 我们再来考虑 “奇怪的点”,一个点 i 变成奇怪的点的条件是:i 是黑色且存在一个白色点 j 满足 j < i && L…
题目链接:BZOJ - 1218 题目分析 可以覆盖一个边长为 R 的正方形,但是不能包括边界,所以等价于一个边长为 R - 1 的正方形. 坐标范围 <= 5000 ,直接 n^2 的二维前缀和,枚举每一个边长为 R - 1 的正方形就 AC 了 = = 但是,尽管 O(n^2) 的算法能水过,lct1999 神犇仍然坚持要写 O(n logn) 算法虐掉这道题,于是我 Orz 他也学着写了一下. 在神犇的讲解下,我写了这个算法: 首先将 n 个点按照 x 坐标排序,用一条竖直的扫描线,从左到…
BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\((a,b,c,d)\),同样也可以二分中位数\(x\),然后把原序列对应地改为\(+1\)或\(-1\). 此时区间\([b,c]\)中的数是必选的,求一个和\(sum\).显然对于区间\([a,b-1]\),我们可以求一个和最大的后缀:对于区间\([c+1,d]\),可以求一个和最大的前缀.然后判断总和是…
BZOJ 3673 BZOJ 3674(加强版) 如果每次操作最多只修改一个点的fa[],那么我们可以借助可持久化线段树来O(logn)做到.如果不考虑找fa[]的过程,时空复杂度都是O(logn). 想要这样就不能加路径压缩,否则要对路径上的点都要改,最好时空复杂度是O(log^2n),但是空间会炸. 合并集合时按秩合并,这样暴力找fa[]的复杂度为O(logn). 再加上线段树就是O(log^2n).(当然空间是O(mlogn)) 具体:可持久化线段树每个叶子节点储存其fa[x].每次按秩合…
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 首先上来两次dfs树链剖分问题不大,然后主要是这三个操作分别如何取实现. 先说第一种,点权修改,直接用线段树的点更新就好了.第二个子树修改,貌似树…