首页 > 其他分享 >[Ynoi2016] 镜中的昆虫 题解

[Ynoi2016] 镜中的昆虫 题解

时间:2025-01-08 11:22:35浏览次数:11  
标签:pre set 颜色 log 题解 Ynoi2016 修改 区间 镜中

[Ynoi2016] 镜中的昆虫 题解

好题值得一做。

题目大意:给一个序列,有若干个离线询问,每次可以区间推平或询问区间内的颜色个数,数据范围是 \(10^5\) 级别。

解题思路:我们可以先考虑一个弱化版,每次是单点修改怎么做,类似于 CF848C

我们考虑维护出每一个位置上一个与它相等的位置是 \(pre_i\),那么区间内数颜色就是求二维偏序 \(l\le i\le r\land pre_i<l\)。

我们又发现,每次单点修改只会有 \(O(1)\) 个位置的 \(pre\) 被修改,可以对每个颜色开一个 set 方便维护每次 \(pre\) 的变化。

之后我们就把修改和查询都离线下来,这样多了时间一维的限制,跑 cdq分治 即可,复杂度 \(O(n\log ^2n)\)。

考虑完弱化版,本题怎么做呢?可以发现即使是区间推平,\(pre\) 数组的总变化量是均摊 \(O(n+m)\) 的。

证明也很容易想,考虑到新推平的区间覆盖了原来的若干个区间,那么只有原来若干个区间的左端点的 \(pre\) 会改变,而区间的其他位置 \(i\) 由于与前面的颜色仍然相同,保持 \(pre_i=i-1\) 不变。而每个区间只会被覆盖一次,一共只有 \(O(n+m)\) 个区间。

当然还有这些被覆盖区间的相同颜色后继区间的左端点会被改变。以及 \(L,R+1\) 也可能改变。但总的还是 \(O(n+m)\)。

实现方面,不仅对每种颜色开一个 set,里面存放这种颜色的每个区间,这样可以方便维护出贡献。还要对所有区间开一个 set,同时存放颜色,这样可以方便地删除区间。

而且我们不要一边删除区间一边算贡献,先把所有可能会改变的点存起来,把它们的贡献去掉,之后修改 set 至当前状态,再把这些点的贡献加上。

对于 cdq分治 部分,不要把询问与修改放在同一个容器里,可以分治时间,把左半时间的修改和右半时间的询问分别放进 vector 里,然后分别排序,然后用双指针扫两个 vector。是不是很类似整体二分的写法呢?

最后 \(pre\) 的变化量是 \(O(n)\) 级别的,用 set 处理是 \(O(n\log n)\),分治部分是 \(O(n\log ^2n)\)。总复杂度为 \(O(n\log ^2n)\)。

标签:pre,set,颜色,log,题解,Ynoi2016,修改,区间,镜中
From: https://www.cnblogs.com/dccy/p/18659352

相关文章

  • Luogu P2414 NOI2011 阿狸的打字机 题解 [ 紫 ] [ AC 自动机 ] [ 离线思想 ] [ 树状数
    阿狸的打字机:非常牛的AC自动机题。暴力先考虑在暴力的情况下,我们如何计算\(x\)匹配\(y\)的次数。显然,我们会模拟往\(y\)里加字符的过程,在此过程中做KMP进行匹配,统计答案。那么如果涉及多个模式串呢?就可以把KMP加强成AC自动机了。考虑在AC自动机上如何刻画这个......
  • CF2057E2 Another Exercise on Graphs (hard version) 题解
    感觉和[NOI2018]归程有点像(?考虑对每个询问二分答案,设二分到的答案是\(x\),要判断路径上的\(k\)大值是否能不大于\(x\),只需先将价值不大于\(x\)的所有边的边权设为\(0\),其他边设为\(1\),跑一遍\(a\)到\(b\)的最短路,看最短路长度是否不大于\(k\)即可。因为\(x\)的......
  • Luogu P3041 USACO12JAN Video Game G 题解 [ 紫 ] [ AC 自动机 ] [ 动态规划 ]
    VideoGamesG:弱智紫题,30min切了,dp思路非常板。多模式串一看肯定就是要建出AC自动机,然后在fail树里下传标记,预处理每个节点到达后的得分。然后设计\(dp_{i,j}\)表示第\(i\)个字符,AC自动机里匹配节点在\(j\)的最大答案,刷表法转移即可:\[dp_{i+1,ch_{j,c}}\gets\ma......
  • HDU7521 cats 的二分答案 题解
    思路首先,转换一下题意。只有在\(val=0\)时,才会向左缩小范围。然而只有越界访问才能达成\(val=0\),因此实际上我们最多只能向左缩小范围\(k\)次。对于当前的二分区间,\(mid\)本身可以作为一个答案,同时还要加上左右两边子区间的贡献。因此想到可以递归计算子区间的贡献。......
  • 题解- 恢复数组
    题目描述有一个数组a[1…n],但是这个数组的内容丢失了,你要尝试恢复它。已知以下的三个事实:1、对于1<=i<=n,都有a[i]>0,且所有的a[i]互不相同。即a数组保存的全部都是正整数,且互不相同。2、x和y一定是属于数组a,且x<y。3、a数组是递增的数组,且相邻两项的差是相等的。即数组a......
  • 海贼OJ #251. 士兵 题解 排序+中位数(数学思维题)
    题目链接:https://oj.haizeix.com/problem/251解题思路:最短总距离是所有点到中位数的距离之和。对\(y\):排序求中位数。对\(x\):对\(x\)排序,然后对排序后的\(x_i-i\)排序,然后求最短距离。对\(x_i-i\)进行处理,能保证最终的\(x_i\)各不一样且相邻。示例程序:#inclu......
  • 题解:P1541 [NOIP2010 提高组] 乌龟棋
    基础动态规划。这道题的题目条件显然满足阶段性和无后效性,那么有一个直观的思路就是把当前所处格子和四种卡片的使用次数作为状态。但是如果按照上面的想法,数组空间是无法开下的,所以我们稍微变一下思路,把四种卡片的使用数量作为状态,对于当前所处格子的话可以直接计算出来,这样数......
  • P8037 [COCI2015-2016#7] Prokletnik 题解
    题意定义一个区间$l,r$为好的当且仅当最小值为$a_l$且最大值为$a_r$或最大值为$a_l$且最小值为$a_r$。我们先考虑最小值为$a_l$且最大值为$a_r$的,另一个我们翻转过来在搞一遍就好了。先考虑将询问离线按$r$排序,容易发现,对于每个右端点$r$对应的合法左端点是......
  • E. Beautiful Array(题解)
    原题链接:https://codeforces.com/problemset/problem/1986/E思路:排序,取模,思维关于操作:ai=ai+k;若要使a1+m1*k==a2+m2*k;则当a1,a2满足a1%k==a2%k,a1,a2可以满足a1+m1*k==a2+m2*k;并在需要(|a1-a2|)/k次操作。将a数组取模后,用vector分别储存,a1和a2相差越小,需要的次数越......
  • 题解:CF2043C Sums on Segments
    题意给你一个长度为\(n\)的数组\(a\),满足\(a\)中有且仅有一个不为\(1\)也不为\(-1\)的数(以下简称特殊的值),剩余的数都是\(1\)或\(-1\)。求所有可能的子区间的和的值(下文简称答案)。从小到大一次输出每一个值,每个值只输出一遍。题解首先,我们发现,如果把那个特殊的值考......