摘要:
题面 这题很有意思,正解做法是线段树优化建图之后跑tarjan强连通分量然后在DAG上做一些奇奇怪怪的统计,但是这题有神仙 \(O(n)\) 做法!(虽然我不会证明但是跑的的确很快啊) 说的是,首先注意到先点一个,最后爆炸的炸弹一定是一个区间。所以现在问题转化成了对于每个 \(i\) 求爆炸的左右端 阅读全文
摘要:
题面 dp有后效性,转移看作边之后会成环。这时候一般需要建出图来跑最短路。 这道题的最短路有些不一样,方程为 \(f_i=\max(a_i,b_i+\sum\limits_j f_j)\),比较像最短路的松弛操作。spfa每次从队列里取出 \(u\) 来之后,遍历所有相邻点 \(v\),记录一个和, 阅读全文
摘要:
题面 看起来就很像是一道数位dp,\(L\) 和 \(R\) 很大,并且限制和大小没关系。考虑状态的设计:剩余长度 \(len\),是否有上限限制 \(lim\),这两个肯定是必须的。因为要统计连续三个位置相同,所以要记录 \(pre1,pre2\) 表示前两位是什么数(当然也可以记录上一位和它们两 阅读全文
摘要:
题面 开一棵线段树,区间内合并左右儿子的时候,如果颜色相同则赋成此颜色,否则直接赋成 \(0\),第三个操作只需要区间 \([l,r]\) 答案不为 \(0\) 且两边颜色不一样即可。比较简单,复杂度 \(O(n\log n)\)。 点击查看代码 #include<iostream> #includ 阅读全文
摘要:
题面 前两个操作放过来看似是一道线段树题,但是发现线段树无法维护第三个操作。考虑使用平衡树(fhqtreap)来解决这个问题,前两个操作和线段树差不多,直接split出来打加法和乘法标记即可。第三个操作大概就是把 \(R\) 位置的系数加到 \(R+1\) 位置并且删除,在 \(L\) 的左边加一个 阅读全文
摘要:
题面 考虑异或可以表示成前缀和的形式,则 \(a[p]\oplus a[p+1]\oplus\ldots \oplus a[n]\oplus x=s[p-1]\oplus s[n] \oplus x\)。后面都是知道的,所以可以拿着 \(s[n]\oplus x\) 的值去01-trie上做匹配。注 阅读全文
摘要:
题面 考虑把操作时间当作下标建立线段树,每次操作要么是单点修改为 \(x\),要么是修改为 \(1\)。输出答案就是输出线段树根节点的答案。 点击查看代码 #include<iostream> #include<cstdio> using namespace std; const int N=1e5 阅读全文
摘要:
题面 本来就是个裸的KMP,但是这个题是有删除的,所以可以维护一个栈,每次的 \(j\) 都继承栈顶元素的 \(j\),然后如果找到了一个匹配,就直接弹栈即可。因为只会进栈 \(O(n)\) 次,所以总复杂度也是 \(O(n)\) 的。这个题算是栈的妙用了。 点击查看代码 #include<iost 阅读全文
摘要:
题面 使用点分治的思想,对每个子树以中心为根dfs一遍算出 \(b,d\) 数组,然后把 \(a\) 数组(子树内所有点)按照 \(d\) 从小到大排序,用两个指针 \(l,r\) 扫数组。注意到这个题需要算个数,所以还需要考虑把在同一个子树内的删掉。另外开一个数组 \(c_i\) 动态维护 \([ 阅读全文
摘要:
题面 这个题相当于是把每个数的值作为 \(x_i\),在原序列中的位置为 \(y_i\),建出笛卡尔树,直接输出先序遍历(字典序最小)即可。 点击查看代码 #include<iostream> #include<cstdio> using namespace std; inline int rd() 阅读全文
摘要:
题解 李超树维护直线,求单点最值。维护线段和直线的区别是,线段只是对一段区间有贡献,在线段树上这一段区间需要对应 \(O(\log n)\) 个节点,然后再往下传 \(O(\log n)\) 次,所以复杂度是两个 \(\log\) 的。直线只需要对整个区间进行这个操作,复杂度是 \(1\log\)。 阅读全文
摘要:
题面 历史最值线段树。考虑到每个区间的操作大概是这样:先是一些加法操作,然后有一次赋值,在这次赋值之后所有的操作都可以表示成赋值。所以维护两类标记,一类表示前面的加法,另一类表示赋值,记录一下这个点有没有开始赋值即可。代码及其难调,建议理清思路再写…… 点击查看代码 #include<iostrea 阅读全文