
线段树
昵称很长很长真是太好了
这个作者很懒,什么都没留下…
展开
-
[CTSC2018]混合果汁 二分 套 主席树上二分
题意:n种果汁,第iii种果汁的美味程度是did_idi有lil_ili升,价格是pip_ipi升mmm个询问,要求使用果汁的总量不小于LimLimLim,价格不超过GGG,最大化所用的果汁的美味程度最小值思路:大体思路:首先二分出来一个taste,然后在比taste高的里面去找一些价格少的,且能凑到L升的果汁,检查是否能凑出。我们发现题目询问很多次,那么我们对于每一次的询问二分,在二分检查时肯定不可以O(n)去检查,因为这样时间复杂度就变成了O(m∗n∗logn)O(m*n*logn)原创 2021-10-18 22:42:48 · 225 阅读 · 0 评论 -
P1502 窗口的星星 离散化+扫描线
题意:一个二维平面上有些点有权值。问给你一个H*W的窗口,问窗口星星亮度总和的最大值。H∗W范围:1e6H*W 范围:1e6H∗W范围:1e6坐标范围:1e9坐标范围:1e9坐标范围:1e9星星数目:1e4星星数目:1e4星星数目:1e4题解:我们考虑一维的情况。假设一个序列aaa,给你你最多可以选择连续长度为lenlenlen序列段,问可以选择出最大的序列和为多少。我们可以将这个(单点修改,区间查询)的问题给转换成,(区间修改,单点查询)问题。初始化一个新数组bbb为0对于第iii原创 2021-10-13 15:43:56 · 158 阅读 · 0 评论 -
[湖南集训]更为厉害 树上主席树-以树深度为下下标建立主席树
题意题解:首先对于树上某个点a来说,假设点b是a的祖先(也就是在a的上面),那么答案很好计算,也就是min(k,dep[a]−1)∗(size[a]−1)min(k,dep[a]-1)*(size[a]-1)min(k,dep[a]−1)∗(size[a]−1)麻烦的就是计算b在a下面的情况。主席树。如何建立这颗主席树呢?按照每个结点的深度建立主席树即可。对于下面的结点来说,我们假设一个结点iii,那么这个结点对答案的贡献则为size[i]−1size[i]-1size[i]−1那么我们在df原创 2021-10-08 14:03:25 · 172 阅读 · 0 评论 -
Naive Operations (线段树 分析复杂度)
题目:给出一个长度为n初值为0的数组,以及长度为n的b数组,然后q次操作,add(l,r) 使得区间l-r所有元素+1,或者查询l~r区间a[i]/b[i]的和题解:很少情况下能很快写出一道线段树题目,关键还0调试首先题目说了b是个排列,突破点也就是b这个条件。因为题目是向下取整,那么假设b[1]=100000,那么你对他修改99999次都是没有任何影响的,那岂不是可以不去修改这个点。同理考虑其他的节点,发现b[i]越大,那么a[i]/b[j]如果变大的话,需要修改的次数也会越多。我们计算一下这原创 2021-09-09 19:15:19 · 259 阅读 · 0 评论 -
Codeforces Round #742 (Div. 2) E. Non-Decreasing Dilemma (线段树维护区间连续问题)
题意:操作1:把x位置的数字修改成y。操作2:查询[l,r]之间不下降序列的个数。题解:线段树维护区间和问题 (这是套路,想不到只能说做题少别打我) 。用五个变量进行维护。sum区间总个数llen从左边这个数字开始往右最长不下降序列长度(往右端最长延伸)rlen从右边这个数字开始往左最长不上升序列长度(往左端最长延伸)lnum这个区间最左端的数字rnum这个区间最右端的数字很明显lnum和rnum很好维护,直接pushup即可。如果左子树的右端小于等于右子树的左端。sum则需要在两原创 2021-09-06 01:41:23 · 326 阅读 · 0 评论 -
P4755 Beautiful Pair (数据结构+分治)
题意:小D有个数列a ,当一个数对(i,j)(i≤j)(i,j)(i\leq j)(i,j)(i≤j)满足 aia_iai和 aja_jaj 的积不大于 ai,ai+1,.........,aja_i, a_{i+1},.........,a_jai,ai+1,.........,aj中的最大值时,小D认为这个数对是美丽的.请你求出美丽的数对的数量。n≤1e5n \leq1e5n≤1e5ai≤1e9a_i \leq1e9ai≤1e9有人推荐笛卡尔树的练习题?但是怎么也想原创 2021-09-04 15:03:00 · 282 阅读 · 1 评论 -
P6617 查找 Search 线段树 查找区间内是否有两个和为w的数(w不变)
题解:每个点x,设置其前驱为离其最近的w-x的位置每次修改可能影响O(n)个位置:w-x x x x x x x…这样后面每个位置的前驱都是w-x如果修改了w-x的值,这样会导致O(n)个修改注意到这个是存在性判定如果存在两个(i1,j1),(i2,j2)(i_1,j_1),(i_2,j_2)(i1,j1),(i2,j2)使得a[i1]+a[j1]=w,a[i2]+a[j2]=wa[i_1]+a[j_1]=w,a[i_2]+a[j_2]=wa[i1]+a[j1]=w,a[i2]+原创 2021-08-28 22:05:22 · 218 阅读 · 0 评论 -
2021牛客暑期多校训练营4 Tree Xor (区间异或上一个数+区间求交)
题解:首先我们可以发现,只要确定了一个值,那么树上其他的值也可以确定下来了,但是显然,遍历一棵树的时间复杂度为O(n),如果枚举+暴力判断的话时间复杂度O(1e9∗n)O(1e9*n)O(1e9∗n)。看了大佬的题解。首先可以假设a[1]=0a[1]=0a[1]=0,然后求出其他的点分别为a[i]a[i]a[i]假设我们把a[1]a[1]a[1]变成xxx,那么其他的点也都会被异或上一个xxx。假设l[1]<0⊕x<r[1]l[1]<0 \oplus x<r[1]l[1]&原创 2021-08-21 22:21:36 · 214 阅读 · 0 评论 -
P3797 妖梦斩木棒 线段树区间合并
题意:1 x C 将第x个小段的木棒替换成C型,C只会是’X’,’(‘,’)’中的一种2 l r 询问妖梦从第l段到第r段之间(含l,r),有多少个完整的木棒完整的木棒左右两端必须分别为’(‘和’)’,并且中间要么什么都没有,要么只能有’X’。题解:典型的线段树维护区间合并问题 (特别注意query中的合并)开三个数组,ls代表左端是否拥有右括号,rs代表右端是否有左括号,ishave用来代表区间中是否有括号。代码:#include<bits/stdc++.h>#define原创 2021-08-12 20:53:02 · 151 阅读 · 0 评论 -
HDU7059-Counting Stars 线段树 (区间加最低位置,区间减最高位)
题意:一个序列,三种操作1.查询序列l,r之间的和2.给l,r之间每个数加上自己二进制最高位3.给l,r之间每个数减去自己二进制的最低位置。题解:我们把一个数分解成二进制的状态进行思考,设cnt为数x当前二进制状态下不为0的位数有多少,我们发现对于两个修改操作,你无论怎么修改,cnt都不会增加,考虑1e9最多有30位不为1的数,你每进行一次操作3,这个数的cnt就会-1,那么每个数最多可以进行30次操作三,多余的操作三没有什么效果。我们可以把一个数分成(最高位+其他位)来进行维护。那么对于操原创 2021-08-12 17:08:56 · 289 阅读 · 1 评论 -
CF703D Mishka and Interesting sum(求区间出现次数偶数次数的异或和)
题意: 给定 n 个数的序列 a。m 次操作。操作有一种:求 al到ara_l到a_ral到ar 中,出现偶数次的数的异或和。n,q<=1e6,a[i]<=1e9n,q<=1e6, a[i]<=1e9n,q<=1e6,a[i]<=1e9题解: 因为本题求得是出现次数为偶数次数的异或和,我们可以知道,两个相同的数异或和为0,那么区间l-r之间的异或和即为出现次数为奇数个数数的异或和,这样我们再求一下区间l-r中不同数的异或和(树状数组老套路),用着两个异或和既可以原创 2021-07-30 11:47:45 · 212 阅读 · 0 评论 -
HH的项链 (求区间内有多少个不同的数字)
这种题之前用莫队做过,这几天看到了一个树状数组的解法,十分巧妙,不卡常,应用广,估计会广泛与其他类型题目结合。题解:由于本题可以离线查询,那么我们将其查询按照右端点进行排序。然后从小到大开始遍历这个序列,如果这个数没出现过,那么我们便在当前位置+1,若之前出现过,那么我们在之前出现的位置上-1,然后当前位置上+1.(因为统计的是不同数字的个数,所以我们统计离r结点最近的即可)。如果遇到r等于i时,我们就统计答案,答案为区间l-r的和。代码:#include<bits/stdc++.h>原创 2021-07-29 19:29:55 · 100 阅读 · 0 评论 -
2021HDU多校第一场 zoto(莫队+分块)
题意:给你一个序列,q次询问,每次询问l-r的区间内数字大小为x-y之间内不重复的个,保证数据所有大小为1e5以内。思路:比赛的时候通过调整了一下分块的大小和各种优化,用莫队把题目给卡过去了,实在是没想到竟然能卡过去qwq,不过我莫队每次移动时的是logn的(套了一个权值线段树),肯定也不是正解(虽然过了)。学习了一下正解,感觉还是自己太菜了qwq。正解把莫队的左右指针移动给变成了O(1)O(1)O(1)的时间复杂度。感觉std的方法还是很巧妙的,用莫队去维护序列的范围,然后用分块来维护数字的大原创 2021-07-23 17:06:15 · 448 阅读 · 0 评论 -
牛客练习赛85 数学家的迷题 (带修莫队/线段树)
题意:1:将a[id]a[id]a[id]的值改为xxx。2:令t=a[l]×a[l+1]×...×a[r−1]×a[r]t=a[l]×a[l+1]×...×a[r−1]×a[r]t=a[l]×a[l+1]×...×a[r−1]×a[r],求t能被多少个不同的素数整除。题解:本题有两种解法,带修莫队和线段树,带修莫队的话需要开个O3提提速,不然会T一个点。1.带修莫队题目不是5e4的范围吗,带修莫队会卡时间?因为莫队移动的操作时间复杂度为O(1),但是这个移动的时间复杂度却不是O(1),应该是原创 2021-06-30 21:52:29 · 212 阅读 · 0 评论 -
CF911G Mass Change Queries (线段树区间 合并)
题意:给出一个数列,有q个操作,每种操作是把区间[l,r]中等于x的数改成y.输出q步操作完的数列.题解:100个数,很容易想到要从这里进行突破,对于某次操作我们只需要把这个区间的数x给移动到y的这个数的集合里面不就可以了。线段树合并!这样的话我们对于每一种颜色动态开一个线段树,合并就把颜色为x的线段树区间l r合并到颜色为y的线段树的区间l r 上即可。之前大多数的线段树合并是整颗线段树进行合并,这个是针对于某段区间进行合并,我们需要稍微调整一下这个update即可。最后只需要遍历一遍这100原创 2021-06-09 21:50:40 · 1117 阅读 · 2 评论 -
[SDOI2011]染色 (线段树维护子段问题+树剖)
题意:给定一棵 n 个节点的无根树,共有 m 个操作,操作分为两种:1.将节点 a 到节点 b 的路径上的所有点(包括 a 和 b)都染成颜色 c。2.询问节点 a 到节点 b 的路径上的颜色段数量。颜色段的定义是极长的连续相同颜色被认为是一段。例如 112221 由三段组成:11、222、1。题解:树剖+线段树维护区间子段和问题。如果在在单独的线段树上操作的话,难度还不是特别高,这个题因为转移到了树上去,树剖的本质是把线段树的区间给分成了好几段,所以我们在经过树上路径的时候,衔接位置要特别注原创 2021-06-08 22:36:24 · 171 阅读 · 0 评论 -
SP10628 COT - Count on a tree (树剖+可持久化线段树)
题意:给定一个包含 N 个结点的树. 树节点从 1 到 N编号.。每个节点有一个整数权值。我们会要求您执行以下操作:u v k : 询问从节点 u 到 节点 v 的路径上的第k小的权值输入在第一行中有两个整数N 和 M(N, M <= 100000)在第二行中有N 个整数, 第i个整数表示第i个节点的权值。接下来的N-1 行, 每行包含两个整数 u v, 它表示有一条边 (u, v).在接下来的 M 行中, 每行有三个整数 u v k, 代表查询从节点 u 到节点 v的路径上权值第k小原创 2021-05-13 20:18:16 · 117 阅读 · 0 评论 -
CF558E A Simple Task 线段树
题解:这种题之前做过一个类似的题目,也是关于选择区间然后给区间进行排序。这种题用线段树把排序转换成区间修改区间求和即可。类似的题目:https://vjudge.net/problem/HDU-5649首先我们看到这个题是针对于字母进行排序的,区间操作很像线段树,那么如何把他转换成线段树呢?我们考虑他只有26个字母,那么我们是否可以转换成维护这26个字母呢?对于每一段区间,我们查询每个字母出现的个数。然后按照题目要求(升序还是降序)然后从l到r依次填从小到大填入字母即可。转换为了区间修改和区原创 2021-04-09 10:03:39 · 150 阅读 · 0 评论 -
Can you answer these queries III (线段树维护最大子段和)
题意:求一个区间的最大连续和。0:表示把A[x]改成y1:表示求[x,y]这个区间的最大连续和。题解:线段树维护四个变量。倒着讲,先来看如何维护这四个变量。summax代表这个区间连续最大值,sum代表这个区间总和,lmax代表区间左端开始最大连序值,rmax代表区间右端开始最大连续值。1.summax:题目要求要连续,所以summax由他下面两端区间计算得出:summax[node]=max(max(summax[ls],summax[rs]),lmax[rs]+rmax[ls]);s原创 2021-02-15 17:48:17 · 188 阅读 · 0 评论 -
Codeforces Round #406 (Div. 1) B. Legacy(线段树上优化建图)
题意:题解:如何处理从v往[l−r][l-r][l−r]每个点进行连边?如果暴力连边就有n2n^2n2条边,无法承受。考虑如何优化区间建图。线段树,它可以在区间询问/修改的时候,把一个区间分成O(logn)O(logn)O(logn)级别个子区间,分别对应线段树上这么多个点。就像这样建图,相当于是建立了两颗线段树,因为线段树递归到叶子结点后,表示的就是单个结点了,那么我们用叶子结点直接表示点。其他的点表示区间,线段树上边的权值为0.比如说v向2-9的点进行连边。我们只需要连接v与2、3、原创 2021-02-15 11:25:58 · 204 阅读 · 0 评论 -
POJ 2828-Buy Tickets(线段树上二分)
题意:有N个人排队,每一个人都有一个val来对应,每一个后来人都会插入当前队伍的某一个位置pos。要求把队伍最后的状态输出。题解:这题我们会发现,如果正着操作,每次加入会带来相对位置的变化,不太好操作。正难则反。我们倒着进行操作。先处理第n个人的位置,第n个人一定是在p[n]+1这个位置上了。当问题规模为n时,确定 n所在位置,删除这个位置后,问题就可以递归成规模为n-1 的问题,因为这 n-1个人的相对位置关系是与n无关的。只是要在考虑绝对位置的时候,留出n所在的空位。那么问题就变成了,一原创 2021-02-14 22:06:07 · 312 阅读 · 1 评论 -
New Year Tree(dfs序+线段树+二进制)
题意: 给出一棵 n个节点的树,根节点为 1。每个节点上有一种颜色 ci。m次操作。操作有两种:1 u c:将以 u为根的子树上的所有节点的颜色改为c。2 u:询问以 u为根的子树上的所有节点的颜色数量。题解:一看题目好像是个dfs序+线段树的板子题,但是需要思考的是,怎么查询一段区间的颜色数目呢?如果把这个问题解决了的话,这个题目也就相应的解决了。看到颜色数目好像并不多,嗷,极好,60(2^60)正好在ll的范围内。我们可以考虑每一位储存一种颜色,返回值为这段区间的**(或)|**。这样子原创 2021-01-15 12:07:37 · 213 阅读 · 0 评论 -
Codeforces Round #686 (Div. 3) F. Array Partition(二分+线段树)
题意:一段区间,让你分割成三段,第一段取max,第二段取min,第三段取max。问你怎么分割这个区间。题解:三个区间我们可以用两个点将一段区间分成三段区间。二分:我们首先找这个题有关的单调性,我们枚举左边的点(也就是l),对于每个枚举的左边的点(l),我们二分找右边的那个点(r)/*Keep on going Never give up*///#pragma GCC optimize(3,"Ofast","inline")#include<bits/stdc++.h>//#def原创 2020-12-05 21:49:39 · 203 阅读 · 0 评论 -
[codeforces] 383C Propagating tree(dfs序+线段树)
题意:给你一棵n个结点的树, 以1为根。每个结点有点权。有m次操作:1.x结点权值 +val,x的儿子权值 −val,x的孙子们 +val,以此类推。2.询问x的点权;题解:我们首先跑一边dfs序,顺便求除每个结点的深度。我们把他分成两颗线段树,深度为奇数的在第一颗上,深度为偶数的在第二课上。我们每次对两颗线段树同时操作。第一颗线段树只进行+操作,第二棵线段树只-操作。当我们询问某个点时,我们只需要判断一下这个点的奇偶,决定查询哪颗树即可。/*Keep on going Never gi原创 2020-11-20 13:53:16 · 202 阅读 · 0 评论 -
求和(dfs序+线段树)
题意:已知有n个节点,有n−1条边,形成一个树的结构。给定一个根节点k,每个节点都有一个权值,节点i的权值为vi。给m个操作,操作有两种类型:1 a x :表示将节点a的权值加上x2 a :表示求a节点的子树上所有节点的和(包括a节点本身)题解:dfs序+线段树用dfs序确定in[x]和out[x]的位置,in是当前结点开始的时间戳,out是回溯到当前结点的时间戳,当查询某结点时,可以快速确定他子树的范围。代码:/*Keep on going Never give up*///#pr原创 2020-11-19 21:50:12 · 250 阅读 · 0 评论 -
CF570D Tree Requests
题意:给定一个以1为根的n个节点的树,每个点上有一个字母(a-z),每个点的深度定义为该节点到1号节点路径上的点数.每次询问 a,b 查询以a为根的子树内深度为b的节点上的字母重新排列之后是否能构成回文串.题解:dfs序+状态压缩+二分查找这个题用到了很多小技巧,比如说异或前缀和等等。我们首先对他跑一边dfs序,记录下每个点的时间戳。把每个层点入度的时间戳放在一起,因为结点到某层,也要保证这一层是他的孩子。所以我们用这个时间戳来确定到底是这一层的哪一段。用二分查找分别找入度结点和出度结点,从原创 2020-11-18 21:18:31 · 139 阅读 · 0 评论 -
选点(dfs序+LIS)
题意:有一棵n个节点的二叉树,1为根节点,每个节点有一个值wi。现在要选出尽量多的点。对于任意一棵子树,都要满足:如果选了根节点的话,在这棵子树内选的其他的点都要比根节点的值大;如果在左子树选了一个点,在右子树中选的其他点要比它小。题解:要满足根节点的值最小,左子树的值大于右子树的值。这样的话我们可以先按照根->右->左的顺序来求出一个dfs序然后求一下LIS即可。/*Keep on going Never give up*///#pragma GCC optimize(3原创 2020-11-17 18:13:42 · 238 阅读 · 0 评论 -
HDU 3333-Turing Tree(线段树解决离线询问)
题意:给定一个长度为n的序列,给定m个查询,每次查询区间[L,R]范围内不同元素的和。题解:x,yx,yx,y为查询的区间左右端点用一个数组left[i]left[i]left[i],表示左边第一个出现相同数字a[i]a[i]a[i]得下标。如果left[i]<lleft[i]<lleft[i]<l,就说明a[i]a[i]a[i]是[x,y][x,y][x,y]中第一个出现的a[i]a[i]a[i]。反之则说明,[x,i−1][x,i-1][x,i−1]中出现过了一次a[i]a原创 2021-02-14 00:29:01 · 262 阅读 · 0 评论