线段树
青烟绕指柔!
我不怕千万人阻挡,只怕自己投降。
展开
-
qko的爱情
题目链接:qko的爱情显然我们只需要没有人的点考虑。对于没有人的点,我们肯定是要使得整个子树向上移动,其实可以看出深度最大的点移动到这里。然后就可以用线段树维护区间最大的深度然后计算答案。我们要注意,计算的时候应该先递归子树,然后对当前没有人的点计算答案,因为对于两颗不同的子树,移动之后最大深度是会发生变化的。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#de原创 2021-07-05 14:46:57 · 210 阅读 · 0 评论 -
文文的摄影布置
题目链接:文文的摄影布置维护左边的最大 A[i] - B[j] ,后右边最大的 A[k] - B[j] ,然后线段树区间合并的时候利用这个和某个区间的max更新答案即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=5e5+10,inf=5e8;int n,原创 2021-07-04 23:28:57 · 160 阅读 · 0 评论 -
圣剑护符
题目链接:圣剑护符能不能异或出相同的数,其实就是看每个数字加入线性基的时候,如果加入不进去,那么肯定能被异或出来。因为线性基最多31个,所以暴力加入判断即可。然后区间异或用树剖+线段树维护即可。AC代码:#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+10;int n,q,a[N],pos[N],bl[N],dep[N],f[N],sz[N],son[N],cn原创 2021-06-30 23:52:36 · 162 阅读 · 0 评论 -
RASPORED
题目链接:RASPORED假设有两个任务,分别为:L1,T1 ; L2,T2如果第一个在前面的代价:L1 + L2 - 2 * T1 - T2反之:L1 + L2 - 2 * T2 - T1所以按照 T 的大小去维护即可。AC代码:#include<bits/stdc++.h>#define int long longusing namespace std;const int N=2e5+10;int n,m,L[N],T[N],sum[N<<2],num[N原创 2021-06-19 18:39:25 · 78 阅读 · 0 评论 -
Codeforces - Cheap Dinner
题目链接:Codeforces - Cheap Dinner因为物品直接的关系都是相邻的关系,不成环,所以可以dp。然后对于每个物品能选的其实是多个区间,且区间个数不超过m之和。所以维护区间min,然后区间查询即可。可以用线段树优化。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;c原创 2021-02-16 20:54:50 · 243 阅读 · 0 评论 -
美丽的建筑
题目链接:美丽的建筑枚举最大值,正反dp即可,用线段树维护区间max。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=1e5+10;int n,mx[N<<2],suf[N],res;struct node{int a,b,c;}t[N];#def原创 2020-11-25 19:08:38 · 183 阅读 · 0 评论 -
HDU - 4747
题目链接:HDU - 4747每次枚举右端点,加入一个数字,维护每个位置的mex,显然很复杂。所以我们考虑每次删除一个左端点,维护前缀mex。考虑当前位置的影响,会影响到后面大于 a[i] 的mex,会变成 a[i] ,直到下一个 a[i] ,所以线段树维护区间修改即可,因为答案是单调递增的,所以线段树区间赋值即可,不用segment beats。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/原创 2020-11-25 00:19:17 · 302 阅读 · 0 评论 -
Data Structure Problem
题目链接:Data Structure Problem考虑递推公式,我们可以发现,答案就是取某个 a[i] 然后一直取 b[j] -> b[x] 。或者全部取 b我们用前缀和化简:令 s[i] 为 i 的前缀和。ans[x] = max { s[x] - s[i-1] +a[i] } = s[x] + max{ a[i] - s[i] }然后用线段树维护即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#includ原创 2020-11-01 17:35:33 · 218 阅读 · 0 评论 -
膜法问题
题目链接:膜法问题显然一个循环节长度为 AB ,那么我们对于所有的区间都可以映射在区间 0 - AB 上面。还有一个结论,如果 r-l+1 >= A * B 那么一定是 0 - A * B 的最大值。否则看 l ,r 映射在了哪个区间即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespac原创 2020-11-01 15:19:34 · 202 阅读 · 0 评论 -
CCPC - Exam Results
题目链接:CCPC - Exam Results我们先按照最大值从小到大排序,然后枚举作为最大值的值。如果满足后面 最小值的max,这个答案就是合法的。然后对于前面做一个尺取维护答案,对于后面的就是一个线段树区间查询。然后枚举某个的最小值作为最大值,我们可以发现必然是最大值最小值才合法,然后线性遍历即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define原创 2020-10-24 11:16:03 · 366 阅读 · 0 评论 -
Codeforces - Pokémon Army
题目链接:Codeforces - Pokémon Army显然每一段下降的连续子串才会贡献答案。我们把整个序列看成多个连续下降的子串即可。然后用线段树维护答案。#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=3e5+10;int n,q,a[N];struct nod原创 2020-09-25 16:56:12 · 195 阅读 · 0 评论 -
茶颜悦色
题目链接:茶颜悦色对 x 方向做尺取,然后对 y 方向维护长度为 k 的最大值。维护最大值的时候,对每个点为正方形的右端点的最大值,然后线段树上区间修改,区间max即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+10;int n,k,m,mx[原创 2020-09-22 16:20:27 · 192 阅读 · 0 评论 -
Codeforces - Two Types of Spells
题目链接:Codeforces - Two Types of Spells简单分析,我们可以发现答案的组成只有几种:1 1 1 0 1 0 0 0…1 1 1 1 1 1…0 0 0 0 0 0…然后其实我们不需要维护这个序列,对每种找到关系即可。假设雷电个数是tot,要么是tot-1个要么是tot个最大值。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#defi原创 2020-09-15 10:02:32 · 169 阅读 · 0 评论 -
Codeforces - Greedy Subsequences
题目链接:Codeforces - Greedy Subsequences把每个点右边最近大于自身的点看成树上的父亲节点,那么我们可以发现找的其实就是一个树上最长链。然后dfs序之后,维护区间+1,-1,区间max即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const in原创 2020-09-11 17:15:36 · 152 阅读 · 0 评论 -
Codeforces - King Kog‘s Reception
题目链接:Codeforces - King Kog’s Reception考虑权值线段树,对每个区间维护这个区间可以延迟到的最后的时间。考虑区间合并:c.sum=a.sum+b.sum;c.lst=max(a.lst+b.sum,b.lst);然后对于查询操作,我们可以发现就是 1 - t 能够到的最后的时间。然后对 t 做差即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc+原创 2020-09-10 10:42:51 · 162 阅读 · 0 评论 -
Codeforces - Lucky Queries
题目链接:Codeforces - Lucky Queries显然区间反转可以用线段树维护。每次反转的时候,对答案的影响就是非严格LIS和LDS的交换。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e6+10;int n,m,lazy[N<<原创 2020-09-02 18:32:27 · 163 阅读 · 0 评论 -
Flags
题目链接:Flags首先这个可以二分。然后这个东西可以 2-SAT,然后我们可以发现我们对每个点连边的时候连的是一个区间。所以我们可以用线段树优化。如果对每个点都建立选 or 不选两个点的话,我们就需要两颗线段树了。我们可以优化一下,对于一个点选的话,我们找到这个区间不能选的点,然后就是连向这个区间所有点的另一个点,也就是选这个点,那么必须选这个区间的另一个点。然后找区间的时候,不能连向自己的反点。AC代码:#pragma GCC optimize("-Ofast","-funroll-al原创 2020-08-21 22:14:26 · 376 阅读 · 0 评论 -
HDU - 4858
题目链接:HDU - 4858因为边很少,我们可以把非树边单独判断。然后每个点相邻的点,其实就是一个BFS序。最后把非树边单独求一下。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+10;int n,st[N],ed[N],dfn[N],m,f[N]原创 2020-08-08 21:22:10 · 198 阅读 · 0 评论 -
Cow Hopscotch G
题目链接:Cow Hopscotch G状态以及状态转移方程很显然,故不再赘述。我们直接考虑转移的优化,我们枚举每一行,然后用线段树维护每一列每一种颜色的方案和。然后每次就可以从不同的颜色转移而来,不同颜色可以用总方案减去当前颜色方案得到。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace st原创 2020-08-06 23:54:03 · 359 阅读 · 1 评论 -
HDU - 6447
题目链接:HDU - 6447显然可以dp,dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+v)然后这个东西可以用数据结构优化。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+10,M=N*40,up=1原创 2020-08-02 23:20:20 · 237 阅读 · 0 评论 -
HDU - 6315
题目链接:HDU - 6315因为每次只会增加1,然后b是一个排列。考虑用线段树暴力维护当前可以更新的叶子节点,我们可以看做是 b 每次减1,减到0就答案增加1,然后把b变回去。极端情况的复杂度:每次更新的叶子节点数是和之前的操作数有关的,所以复杂度是正确的。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing na原创 2020-07-30 10:32:12 · 275 阅读 · 0 评论 -
HDU - 6681
题目链接: HDU - 6681显然这是一个平面图,我们可以根据欧拉公式:V - E + F = 2假设射线之间交点个数为x,有n条线段。那么V = 4 + x + 2*n , E = 4 + 2*x + 2*n所以:F = 2 + E - V = x + 1所以我们维护交点个数即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define in原创 2020-07-29 21:45:43 · 228 阅读 · 0 评论 -
可重集
题目链接:可重集显然这种题就是用各种hash去做的。如果是判断一个区间是否完全相等,我们可以给每个值换一个随机值,然后区间异或哈希。但是现在是差分相等,如果是区间异或的话,做加法很困难。所以我们可以考虑用次幂哈希。例如:5 = base ^ 5这个就很好做加法了。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusin原创 2020-07-29 16:13:26 · 606 阅读 · 0 评论 -
HDU - 6638
题目链接:HDU - 6638枚举x的范围,然后对y做一个区间最大连续子段和即可。但是要注意处理相同x的情况。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=2e3+10;typedef long long LL;int n,m; LL res;stru原创 2020-07-29 11:43:58 · 287 阅读 · 0 评论 -
HDU - 6606
题目链接:HDU - 6606显然可以二分。然后二分之后,我们就可以dp了,dp[i]=max{dp[j]+1},保证j+1到i的和小于等于mid即可。然后这个显然是区间max,可以用线段树优化,这道题很恶心,卡空间了,所以我们必须离散化。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace st原创 2020-07-29 00:13:33 · 325 阅读 · 0 评论 -
HDU - 6464
题目链接:HDU - 6464维护每个数字的个数,以及区间和。对于每次查询,我们可以在线段树上二分到需要的区间,然后注意一下端点不一定会取完。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=1e5+10,M=N*40,mod=1e9+7;int n,num[M]原创 2020-07-25 22:02:35 · 195 阅读 · 0 评论 -
弹钢琴
题目链接:弹钢琴对音高排序之后,不难发现是一个最大权值的LIS问题。线段树即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=1e6+10;int n,mx[N<<2],m;struct node{int a,b,c;}t[N];vector&l原创 2020-07-25 19:13:01 · 119 阅读 · 0 评论 -
小A与最大子段和
题目链接:小A与最大子段和假设我们设一个前缀和为:sum[i] = sum[i-1] + i * a[i] , s[i] = s[i-1] + a[i]那么我们答案可以表示为:sum[r] - sum[l-1] - (l-1) * (s[r]-s[l-1])化简可得:sum[r] + {-(l-1)*s[r]-sum[l-1]+(l-1)*s[l-1]}把(l-1)当成斜率,-sum[l-1]+(l-1)*s[l-1] 当成截距,然后就可以斜率优化dp了。这里我采用了之前没写过的李超树维护原创 2020-07-22 20:06:24 · 206 阅读 · 0 评论 -
异或树
题目链接:异或树显然可以按二进制位计算。然后因为是子树查询,所以我们可以从下到上做线段树合并。然后每个值因为只要奇数次,那我们按照异或去更新即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=1e5+10,M=N*40;int n,q,w[N],res[N]原创 2020-07-22 14:19:02 · 227 阅读 · 0 评论 -
Codeforces - Let Them Slide
题目链接:Codeforces - Let Them Slide因为序列的长度之和小于1e6.所以我们只要对每一次操作是O(长度)那么就是ok的。若:l*2<=w那么有很多区间的位置都是全部能贡献的,所以左右端点区间暴力更新,中间的直接用最大值更新。否则:枚举总区间的每个位置。看能贡献的地方,然后区间max。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#d原创 2020-07-20 22:24:14 · 172 阅读 · 0 评论 -
Codeforces - Propagating tree
题目链接:Codeforces - Propagating tree一颗线段树 or fenwick是可以做的,不过各种打标记,很复杂。我们对奇数和偶数深度的分别开一颗线段树即可。然后同深度加,不同深度减。然后对于子树区间,dfs序搞搞就行了。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace原创 2020-07-19 23:07:31 · 161 阅读 · 0 评论 -
Codeforces - Addition on Segments
题目链接:Codeforces - Addition on Segments选任意条最大值为k,其实就是看一个点能到的值。我们把每个线段打在线段树的区间上面,看每个叶子节点能到的值即可。类似于线段树分治。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e4原创 2020-07-19 12:12:52 · 146 阅读 · 0 评论 -
Codeforces - Diverging Directions
题目链接:Codeforces - Diverging Directions我们直接考虑距离的几种情况。假设:x->y的一条边如果y在x 的子树中,那么直接就是两点之间的距离。否则:一定是x先向下走,然后到1号节点,然后到yres = min{dis[t]+f[t]}-dis[x]+dis[y]所以我们需要找到子树中最小的min{dis[t]+f[t]},线段树维护子树的这个区间min即可。AC代码:#pragma GCC optimize("-Ofast","-fu原创 2020-07-17 11:21:41 · 193 阅读 · 0 评论 -
Codeforces - Ant colony
题目链接:Codeforces - Ant colony看区间是所有数字因子的数的个数,其实就是看区间等于区间gcd的数的个数。我们直接线段树区间维护这个个数即可。或者维护区间gcd,然后主席树计算区间等于gcd的个数。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const i原创 2020-07-16 23:49:31 · 162 阅读 · 0 评论 -
Earthquakes
题目链接:Earthquakes势能线段树的思想,因为每次最多增加一个点,然后我们只需要暴力修改即可。但是要快速枚举到需要修改的区间,用区间mi即可。然后修改的时候要pushup,所以不能用函数返回值。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+原创 2020-07-15 17:40:44 · 157 阅读 · 0 评论 -
Number of Inversions on Segment
题目链接:Number of Inversions on Segment因为值域很小,合并区间的时候枚举值域即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing namespace std;const int N=1e5+10;int n,q,a[N],sum[45];struct node{int res,cn原创 2020-07-15 17:07:04 · 290 阅读 · 0 评论 -
Disruption P
题目链接:Disruption P可以发现,如果某条边可以弥补当前边的缺失,那么这条边在树上的路径一定会经过这条边。所以我们对每条树上路径取min即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=5e4+10,inf=0x3f3f3f3f;int n,m原创 2020-07-15 14:25:18 · 192 阅读 · 0 评论 -
Happy Triangle
题目链接:Happy Triangle比赛的时候,考虑相同的数字的时候处理错了。然后浪费了4个小时。能和x构成三角形,我们不难想到如果某一个大于x的值y,与另一个数z之间的差值y-z<x,那么就是合法的。不然我们可以贪心选择两个小于等于x 的数,看是否大于x。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing原创 2020-07-13 20:57:11 · 267 阅读 · 0 评论 -
This Problem Is Too Simple!
题目链接:This Problem Is Too Simple!因为每次只查询一种颜色,所以我们可以直接对每一种颜色开一颗线段树。如果是多种颜色就需要树套树了。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+10,M=N*80;int n,q,val原创 2020-07-11 09:24:40 · 292 阅读 · 0 评论 -
Tree
题目链接:Tree显然可以启发式合并,然后对于每个点我们要快速找到对应的另一个权值,然后距离小于某个值的个数和。显然可以线段树维护,所以我们对每一种权值都维护一颗线段树即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1e5+10,M=N*80;int原创 2020-07-09 09:06:10 · 215 阅读 · 0 评论