数据结构专项训练
我只是个记录思路的题记。
注:点标题进题目链接。
线段树
SPOJ GSS
比较有思维含量的题单,非常值得做一做。
P4145 上帝造题的七分钟 2
因为有开方操作,不能懒标记要直接修改,注意减枝区间最大值小于1时开方无意义,不操作。
[ABC341E] Alternating String
区间前缀后缀的模板提升题,其实求最大字段和也是这个意思。
维护端点的数字,最大前缀合法,最大后缀合法,和最长合法长度。
其中最长合法是判断左区间右端点异或右区间左端点是否合法,合法就可以转移过来(左最大后缀和右最大前缀),否则就从左合法或右合法转移,那怎么维护前缀合法呢,如果左区间全合法那最长前缀合法就取最长左长度和右最长前缀,后缀同理。
如何查询,如果区间在左右子树上那就考虑将左右子树合并计算,否则就递归地查询左或右子树,如果合法长度等于查询区间长度就代表是合法的。
[ABC331F] Palindrome Query
如何判断是回文串呢,你不会说是马拉车吧还是暴力求,那这题哪个都难以实现,所以我们想到用 hash,如果是回文的话哈希值相同的,所以我们就明确了,维护前缀的值和后缀的值(或者说正着加),最后判单是否相同。
hash 注意溢出,子树合并也要会哦!!!
P1438 无聊的数列
看到这题你是不是想的是区间多次加,嘿嘿,那你就和我一样了,我们考虑用线段树维护差分数列,每次加操作都是头节点、中间、尾节点后一位的数增加,单个数就是前缀和,这用区间加区间查询的线段树非常容易实现。
P2824 [HEOI2016/TJOI2016] 排序
这做法很 nb 震撼我一百年,我们先思考 01 串如何排序,对于 01 串 0101110
我们对他升序排序后为 0001111
这就类似一个区间修改操作,将前部分变为 \(0\) 后半部分变为 \(1\) ,降序也是如此操作。
但我们并不是 01 串,但是我们这题有单点查询和查询一次不强制在线的特点,所以我们就二分答案,将大于等于 \(mid\) 的为 \(1\),小于 \(mid\) 的为 \(0\),然后我们修改完后判断当前位置是否为 \(1\) 然后调整二分区间,最后答案就是那个数。
P3792 由乃与大母神原型和偶像崇拜
想到了带修莫队查不同值,线段树查最大最小值求区间长度,正解为线段树维护区间平方和再维护最大值最小值,再手动算最大值到最小值之间的平方和是多少,判断是否相同,类似哈希思想。
\(ans\) 数组先判断 \(\max-\min\) 这个是互不影响的,并且之后不要没莫队结果不对不归零,我就这么唐!!!