合集-区间问题
摘要:原题链接 题解,好多细节。。 1.构建st表时的细节 2.数越多,按位与的结果越小,所以对于 \(f(l,i)\) 存在 \(r_{max}\) 使得 \(i>r_{max}\) 时 \(f(l,i)<k\) 小于等于时相反,故具有单调性 但是,在倍增结构上二分你玩原神玩多了? 向右遍历即可,直到
阅读全文
摘要:原题链接 code #define ll long long #include<bits/stdc++.h> using namespace std; ll tree[410000]={0}; ll wait_mul[410000]={0}; ll wait_add[410000]={0}; ll
阅读全文
摘要:原题链接 题解 多次单点修改加上多次区间查询 线段树 code #include<bits/stdc++.h> using namespace std; int tree[800005]={0}; int a[200005]={0}; void build(int node,int l,int r)
阅读全文
摘要:原题链接 题解 区间修改+单点查询 对于一个点,查询的时候翻转的次数如果是奇数,是1,如果是偶数,是0 所以题目转变成对区间上的点加一,然后求单点的奇偶性 树状数组 对一串序列加1,相当于对其差分序列的 \([l]++,[r+1]--\) code #include<bits/stdc++.h> u
阅读全文
摘要:原题链接 题解 标准的线段树加上一点点题意转化,注意细节 code #define ll long long #include<bits/stdc++.h> using namespace std; ll tree[810000]; ll wait[810000]; inline void read
阅读全文
摘要:原题链接 题解 一只青蛙 \(x\) 天来回跳 $\to $ 一只青蛙从左往右跳 \(2x\) 次 \(\to\) \(2x\) 只青蛙从左往右跳一次 规律:对于任意长度为 \(y\) 的区间,其区间和一定不小于 \(2x\) 证明过程请看题解区,非常优雅 upd: 如果想从起点跳到石头上,那么前y
阅读全文
摘要:原题链接 题解 对于原序列而言,如果第一个元素是最大值或最小值,那么l肯定不能落在这,由于r也不可能落在这,所以相当于这个元素被剔除了 那么对于区间 \([1,n]\) 的研究就等价于对 \([2,n]\) 的研究 由此可以推出之后的做法 code #include<bits/stdc++.h> u
阅读全文
摘要:原题链接 题解 单点修改线段树,向上更新,再注意下转移方程就行了 code #include<bits/stdc++.h> using namespace std; int tree[800005]={0}; int len[800005][2][2]={0};//代表第几个节点,0/1在左/右边的
阅读全文
摘要:原题链接 题解 对于任何一个粘液块s而言,要么是从左边被吞并,要么是从右边被吞并,根据对称性,两边的决策是一样的,因此先考虑右边 对于被右边吞并而言,有以下几个特征 1.起始粘液一定是吞掉了s右边一整块连续的粘液 2.右边区间一定存在大小不同的相邻粘液,这样才能发动吞并 3.由一二猜想,只要存在不同
阅读全文
摘要:原题链接 题解 计算分数是搜索 存储前缀注意细节 code #include<bits/stdc++.h> using namespace std; #define ll long long ll sco[35][35]={0}; string pre[35][35]; ll a[35]={0};
阅读全文
摘要:原题链接 题解 我们发现,当前的决策会影响未来的结果,因此我们把当前的决策存下来,这样等未来要用的时候就有的转移了,如果未来由多个状态决定,那就现在把那些状态都记录下来 我们发现,一个点如果能被吸收,那么其左边或右边的一个区间的点都肯定被吸收了,所以我们记录 \(f[i][j]\) 表示区间 \([
阅读全文
摘要:原题链接 题解 二分加动态维护区间最大值 注意设立变量的含义,改变变量值的规则 code #include<bits/stdc++.h> #define ll long long using namespace std; ll sum[500005]={0}; struct unit { ll x,
阅读全文
摘要:原题链接 题解 代码量小的离谱,思维难度大的离谱 对于两个原本不相邻的同色区域块,历经千辛万苦碰面的场景,我们可以描述成右边的区域块为左边的区域块消除的时候增添了长度 设 \(dp[i][j][suf]\) 代表消除区域 \([i,j]\) 同时该区域的 \(j\) 增添了长度 \(suf\) 但是
阅读全文
摘要:原题链接 题解 把覆盖的区域变成黑色,然后在区域内划几条竖线,一定能分成若干个矩形左右拼接而成的图形 想象一条竖着的线,它的运动轨迹是不连续的,即他会从一个矩形的竖边跳到另一个矩形的竖边,每跳一条竖边都会对借着竖边归属的矩形的信息对这条竖边的激活块进行修改 当竖线的绝对位置发生移动时,计算激活区间产
阅读全文
摘要:原题链接 审题 1.连续子序列:子序列必须连续 2.最小长度为1 3.子序列之间至少隔一个数 题解 令 \(presum[i]\) 代表i及其之前的最大前缀和 则第一步更新令 \(presum[i]\) 为必须包括i的最大前缀和,第二步更新令其为i及其之前的最大前缀和。 sufsum同理 最后枚举断
阅读全文
摘要:原题链接 题解 1.我们没法遍历每个区间然后找出他们的最小值,所以我们考虑每个元素对答案的贡献 2.对于每一个元素来说,它的贡献等于它所在的区间长度乘上自身的值,这里的区间指的是以它为最小值的区间 3.以每个元素为最小值的区间要怎么求呢?我们将其转换成求左边第一个小和右边第一个小 对于这种问题(求序
阅读全文
摘要:原题链接 题解 1.修改树上某一段路径 ,最后问你单个点的最大值,很想区间修改,单点查询,且只查询一遍,所以我们往前缀和方向靠 2.一个节点只有一个父亲,所以从底到根的路径是一条链,我们可以在这里应用前缀和,标记策略为令 \(tree[now]++\) 代表 \(now\) 节点到根节点这条链上所有
阅读全文
摘要:原题链接 题解 1.小模拟+树上差分+lca code #include<bits/stdc++.h> using namespace std; int a[300006]={0}; vector<int> G[300005]; int depth[500005]={0}; int fa[50000
阅读全文
摘要:原题链接 题解 dalao‘s blog 我自己的认识请看代码区 code #include<bits/stdc++.h> using namespace std; int n,Q,root,mod; int bigson[100005];//和自己在同一条链上的儿子节点 vector<int> G
阅读全文
摘要:原题链接 题解 1.一眼数位dp, 康托是谁?不认识,在每一位确保小于的时候可以任意取 2.阶乘一开始就要放好 3.在遍历到后面几位的时候,可能前面几位用过了比x小的树,所以我们要知道小于x且没被用过的个数,这就是区间查询加单点修改,树状数组比较方便 4.树状数组的空间复杂度比较小,每个点就对应且只
阅读全文
摘要:原题链接 题解 1.观察数据法:看到 \(1e^5\) 想到线性递推,想到遍历每头奶牛试着在它们后面添加隔断时的分组方案数 2.对于奶牛 \(i\) 它的状态转移方程为 \(dp[i]+=dp[j];j<i;sum[j]<=sum[i]\) 3.上述可以把 \(sum\) 看成 x轴, \(dp\)
阅读全文
摘要:原题链接 题解 莫队算法是局限性非常大的优化,离线+无修改,它通过邻近区间修改复杂度为 \(O(1)\) 的特性让区间排序,然后再做修改,排序的规则是按块排序,然后左端点 \(l\) 在一个块里的按右端点排序 code #include<bits/stdc++.h> using namespace
阅读全文
摘要:原题链接 题解 1.由于每个点最多修改6次,所以我们可以暴力循环遍历所有点进行修改。然后可以把无需再修改的点跳过,即并查集,指向右端第一个仍然需要修改的值的下标 这样就是单点修改加区间查询,树状数组 时间复杂度 \(6·n·log(n)\)(单点修改)+ \(m·2·log(n)\) (区间查询)
阅读全文
摘要:原题链接 题解 ,太不容易了 \(a_i!=a_j\) 所以对于每一个数而言,最多有两个配对,最少有一个配对。即排序之后,前后哪个离自己更近就和谁配对 \((x,y)!=(y,x)\) 把配对看成区间 令 \(tree[i]\) 代表有多少个区间的左端点大于 \(i\) 把查询按右端点排序,顺序遍历
阅读全文
摘要:原题链接 题解 找出右端点大于等于当前区间的左端点且左端点小于等于当前区间的右端点的所有区间,由于查询前这样的区间具有单调性,所以可以用二分,但是怎么快速删除呢? 欸stl大法来了,用set存储区间,查找和删除和添加都是 \(logn\) 级的 code #include<bits/stdc++.h
阅读全文
摘要:原题链接 题解 1.如果能分成偶数个区间,那么一定能分为两个区间 2.如果能分为奇数个区间,那么一定能分为三个区间 3.能分为两个区间,说明区间异或和为 \(0\) 4.能分为三个区间,这三个区间分别为区间 \(a,b,c\) ,则 \(ab\) 区间异或和为零, \(bc\) 区间异或和为零 co
阅读全文
摘要:原题链接 题解 1.如果 \(x \oplus y \gt x\) ,则 \(y\) 的最高位对应的 \(x\) 一定是 \(0\) 2.$f(x,y)\oplus f(y,z) \gt f(x,z) $ 等价于 \(f(x,z) \oplus a_y \gt f(x,z)\) 3.\(x \in
阅读全文
摘要:原题链接 题解 1.常见思路: \(dp[l][r]\) 为把 \([l,r]\) 内的元素全部消掉留下一个元素的值,然后枚举中间点 但是这样内存不够,观察到 \(a_i \in [1,40]\) ,我们可以换个思路,由于区间 \([l,r]\) 内全部消掉留下一个元素的值 \(v\) , 其中 \
阅读全文
摘要:原题链接 题解 1.复杂问题简单化,把字符用数字代替 2.每次替换都会减少一个字符,到最后一定是由两个字符合成一个字符,并且这两个字符的来源区间不相交 3.相同区间不同的合并方式,最后生成的字符也不同,所以dp多加一个状态 4.题目只问能否合成对应字符 code #include<bits/stdc
阅读全文
摘要:原题链接 题解 巧妙模拟题 1.\(n\leq 5000\) 所以可以暴力枚举k 2.把翻转的区间具象化,我们可以发现序列中值为 1 的地方覆盖了偶数个区间, 0 的地方覆盖率奇数个区间 所以我们遍历字符串的时候,在遇到的第一个0开始建立以其为左端点的区间,如果遇到 1 的区间覆盖数为奇数,那就再建
阅读全文
摘要:原题链接 题解 题意提醒: 这里的时间段要抽象成点,比如 \([1,1] , [2,2]\) 实际上是相连的!! 1.朴素想法,每头牛要么值班要么不值班, 搜索遍历所有情况 \(O(2^n)\) 2.稍作修改,如果一头牛值班,那么在它值班结束时间之前值班的牛的数量一定是最优的,\(o(nT)\) 3
阅读全文
摘要:原题链接 题解 注意数据范围 1.我们不知道要在哪些地方建站,所以考虑都遍历一遍 2.如果一个地方 \(i\) 要建站,那么在它前面且离它最近的一个站,一定建在所有右端点大于 \(i\) 的区间中,左端点最大区间里 所以我们令 \(dp[i]\) 表示为在 \(i\) 建立一个站,且和 \([1,i
阅读全文
摘要:原题链接 题解 首先,玩家一先选,那么玩家一该选最左边还是最右边呢? 我们假设玩家一有穿越时空的能力,知晓了选择左边后的最大得分和选了右边后的最大得分,那么玩家一便能确定选哪个 设 \(dp[l][r]\) 为当区间为 \(l,r\) 时先手最大分数 选左边的最大得分: \(sumr-dp[2][r
阅读全文
摘要:原题链接 题解 1.暴力枚举每一个区间,然后加和 \(\to \ O(n^2)\) 如何优化?考虑到区间异或和不一定每一位都对答案有贡献,所以我们只考虑对答案有贡献的区间 2.遍历每一位,找出能使他对答案有贡献的区间个数,再乘上区间长度 细节 由于有求模运算,所以减法可能会出现负数,通过加一个模数解
阅读全文
摘要:原题链接 题解 假设最优解的最大值点在x,那么我们可以把所有和x无交集的线段全部删掉,抽象地感觉,从x往两边扩散,每个点覆盖的线段数越来越少,因此最小值点不是在1,就是在m 由于已知最小值点,我们把所有和最小值点有交集的线段全部删掉,这样假如最大值点和最小值点有共同线段,不改变答案,假如没有共同线段
阅读全文
摘要:原题链接 题解 每个点要么喂,要么不喂,我们令 \(dp[i]\) 为前 \(i\) 个步骤最多能喂养多少猫,易得 \(dp[i]\) 是单调不减的 我们再维护每个点被包含的区间里的最左端 \(l\) 这样一来 \(dp[i]=max(dp[i-1],dp[l-1]+sum)\) 可是如何维护每个点
阅读全文
摘要:原题链接 题解 只要求最大值和最小值的差尽量小,也就意味着,权值位于最大值和最小值之间的线段可以任意取 也就是说,我们将线段按权值排序,我们只需要取其中一段区间,然后查看是否覆盖了完整的区间,如果是,判断能否更新最小值 这样看起来是两次for循环找区间,对于查看是否完整覆盖区间的部分,看起来是对区间
阅读全文

浙公网安备 33010602011771号