回滚莫队
例题:历史的研究
题目描述
$IOI$ 国历史研究的第一人——$JOI$ 教授,最近获得了一份被认为是古代 $IOI$ 国的住民写下的日记。$JOI$ 教授为了通过这份日记来研究古代 $IOI$ 国的生活,开始着手调查日记中记载的事件。
日记中记录了连续 $N$ 天发生的事件,大约每天发生一件。
事件有种类之分。第 $i$ 天发生的事件的种类用一个整数 $X_i$
表示,$X_i$ 越大,事件的规模就越大。
$JOI$ 教授决定用如下的方法分析这些日记:
选择日记中连续的几天 $[L,R]$ 作为分析的时间段;
定义事件 $A$ 的重要度 $W_A$ 为 $A\times T_A$,其中 $T_A$ 为该事件在区间 $[L,R]$ 中出现的次数。
现在,您需要帮助教授求出所有事件中重要度最大的事件是哪个,并输出其重要度。
注意:教授有多组询问。
输入格式
第一行两个空格分隔的整数 $N$ 和 $Q$,表示日记一共记录了 $N$ 天,询问有 $Q$ 次。
接下来一行 $N$ 个空格分隔的整数表示每天的事件种类。
接下来 $Q$ 行,每行给出 $L,R$ 表示一组询问。
输出格式
输出共有 $Q$ 行,每行一个整数,表示对应的询问的答案。
数据范围
对于 $100%$ 的数据,$1\le Q,N\le 10^5$,$1\le X\le 10^9$,$1\le L\le R\le 10^5$。
样例输入 #1
1 | 5 5 |
样例输出 #1
1 | 9 |
样例输入 #2
1 | 8 4 |
样例输出 #2
1 | 27 |
样例输入 #3
1 | 12 15 |
样例输出 #3
1 | 18 |
一、回滚莫队算法
分析题目,没有修改,只有问询,似乎只是一个普通莫队。但如果用普通莫队去做就会发现写不了删点操作,因为无法确定删除掉的是不是最大的那个。
所以我们就改变一下思路:
既然删点难写那么咱们就改变思路:不删点。
但每个问询区间大小不一,无法保持只加点不删点。
其实可以保持右端点只增不减,对于左端每次增点后用暴力把增点数据删除(即回滚)即可。
由于要保证右端点只增不减,即不能使用奇偶优化。排序函数这么写
1 | sort(q, q + m, [&](const Query &x, const Query &y) { |
二、完整代码
时间复杂度:$O(M\sqrt{N})$
1 |
|