2024.10.10
Last Update:
Word Count:
Read Time:
代码能力怎么这么弱?代码能力怎么这么弱?代码能力怎么这么弱?
昨天调题调破防了,忘了写。今天补上。
增加是好维护的,删除是不好维护的,考虑回滚莫队。
可以用栈维护一下,然后栈序撤销。
但是写挂了,不想调,所以没有代码。
upd:唐。
今天把代码补了,发现自己以前唐完了。
以前我对每个颜色只记录了最左侧的位置,然后一直错。
事实上应该记录最左侧和最右侧的位置。
不知道自己怎么做到这么唐的。
代码事实上很好写。
1 |
|
首先,你要先读对题。
题目让求的是出现次数的第k小,不是第k小的出现次数。
且这个第k小是不去重的。
因为读错题又挂了半天,呃呃。
区间查询,容易想到莫队。
值域上的第k小且要平衡复杂度,容易想到值域分块。
莫队加值域分块即可。
1 |
|
因为是重排以后的回文串,所以这个限制本质上就是对每种字符的出现次数的奇偶性的限制。
因为我们只关心奇偶性,所以想到异或。
因为字符集很小,所以考虑状压。
我们用一个 26 位的数表示每种字符的出现次数的奇偶性。
那么对于一个区间,我们可以先把前缀异或求出来,然后就很好得到区间异或值了。
设 为前缀异或,询问区间为 ,那么询问就被转化成了:在 种选取两个不同位置 ,使得 等于 0 或 2 的若干次方(0 代表每种字符都出现偶数次,2 的若干次方代表只有一种字符出现奇数次)。
指针移动时的修改就对每种字符都算一下就行。
和[CQOI2018] 异或序列很像。
事实上可以二离做到更优复杂度,但是没必要,字符集太小了。
1 |
|
首先得先把这个游戏想明白。
事实上是个简单贪心。
不难发现,从小往大消除就是最优的。
然后手玩样例可以发现,最后得到的最优结果就是最小的出现次数为偶数的数的后继。
不难理解,因为你可以先把小于这个数的数全消成只剩 1 个,然后把这个数消没,最后得到的就是这个数的后继。
而且这一定是最优的。
假设它的后继不是最优,那么我们最后能得到一个比它的后继大的数,那么这就要求这个数的后继和这个数最后必须被消没。
但因为这个数出现次数为偶数,所以它不能被大数消除的亡语给带没。所以如果我们要把它的后继给消没,那么此时的结果就是这个数。这是不优的。
如果我们先把这个数消没,那么得到的一定是后继。
命题得证。
那么现在问题变成了:单点修改,区间查询值域在一段区间上的数里,最小的出现次数为偶数的数的后继。
先不考虑修改,容易想到莫队。
那么需要维护值域上的信息,容易想到值域分块。
因为要带修,所以带修莫队+值域分块即可。
值域分块维护每个数的出现次数,每个块内出现次数为偶数的数的个数,每个块的数的个数(去重或不去重都行,没必要去重,但我写的去重)。
查询时,我写成了查两次:先找出来最小的出现次数为偶数的数,然后找这个数的后继。
感觉比较好理解。
但我很唐,所以写出来了一堆唐氏错误:
- 第一次查完得到 ,第二次应该查 ,我写的
- 第一次查完得到 , 可能等于 ,此时再查 会查出抽象东西。
- 带修莫队的询问编号编错了,导致答案存到了未知地方。
1 |
|
二分图匹配肯定是假的,先转化题意。
首先,把 转化成 。
令 ,转化为则 。
因为点的顺序不影响匹配,所以按点权从大到小排序,不难发现每个右部点对应的都是一段前缀。
现在问题转化为:给一个序列,每个点都有一个可供安排的前缀区域,每次区间查询,把该区间的点拿出来,最多能安排几个点。
首先想到莫队。
然后这东西想了半天没想出来怎么维护,最后发现可以线段树维护。
我们维护安排区域上的线段树。
每个节点上维护三个信息:区间大小(),区间内尝试过安排的数的个数(),区间内成功安排的数的个数()。
指针移动时的修改就是单点修改。
贪心地,我们在这个点可供安排区域的右端点修改。
若该位置还未被匹配,则该点 和 +1,否则只有 +1。
删除是同理的。
然后考虑怎么合并信息。
关于合并, 直接相加即可。而 ,要先把左右相加,然后考虑能否多匹配几个。
这东西就是 ,也即是 。
可能会有疑问:为什么不把左边多的给右边?
因为我们每次都是贪心地把每个点插到自己的区域的右端点,所以肯定是右边会多。
复杂度
然而我用 upper_bound 传了个 greater 预处理每个点的安排区域写挂了,只有 95pts。
然后把这东西改成线段树上二分就行了。
呃呃,不知道哪里写错了,看来还是慎用 STL,尤其是不确定这么写会不会出问题的时候。
1 |
|