时间限制: 1 Sec 内存限制: 128 MB
提交: 61 解决: 2
[提交] [状态] [命题人:admin]
题目描述
IOI 国历史研究的大牛——JOI 教授,最近获得了一份被认为是古代 IOI 国的住民写下的日记。JOI 教授为了通过这份日记来研究古代 IOI 国的生活,开始着手调查日记中记载的事件。
日记中记录了连续N天发生的事件,每天发生一件事件。
事件有种类之分。第i天发生的事件的种类用一个整数Xi表示,Xi越大,事件的规模就越大。
JOI 教授决定用如下的方法分析这些日记:
1.选择日记中连续的一些天作为分析的时间段;
2.事件种类t的重要度为t×(这段时间内重要度为t的事件数);
3.计算出所有事件种类的重要度,输出其中的最大值。
请制作一个帮助教授分析的程序,每次给出分析的区间,你需要输出重要度的最大值。
输入
第一行两个空格分隔的整数N和Q,表示日记一共记录了N天,询问有Q次。
接下来一行N个空格分隔的整数X1,...Xn,Xi表示第i天发生的事件的种类。
接下来Q行,第i行有两个空格分隔整数Ai和Bi,表示第i次询问的区间为[Ai,Bi]。
输出
输出Q行,第i行一个整数,表示第i次询问的最大重要度。
复制样例数据
5 5
9 8 7 8 9
1 2
3 4
4 4
1 4
2 4
样例输出
9
8
8
16
16
提示
想着没啥思路就写莫队,然后一直变换着t和wa,最后发现自己缺个知识点、、、
回滚莫队,一开始没看懂,后来发现这东西还真是名副其实的在滚、、
考虑一般莫队,复杂度是,但是这题要求区间最值,那,要维护区间最值的话,
只能是再套个其他的数据结构,复杂度就变成了,没法再优化,
区间最值问题要维护只能是级别的
这时候我们注意到,如果区间一直扩张的话,最值其实可以取到,
但是如果区间在缩小的话,那就没办法了,所以,如何避免区间缩小这种情况呢
由分块的sort,想到,对于l在同一个块内的r,其实是不断递增的,
如果不考虑l的话,那再好不过了(l定住,r不断向右递增,所以区间是扩大的)
现在考虑怎么消除l的影响?
要是,要是l是每次递减的就好了,但是,很可惜,不是
怎么办、、、人为制造递减,,,
如果r在块外,l在块内,
例如
---|---L------|-----R-----
这样,r每次递增那就不管他和原来的莫队一样就行
l每次设置在下一块的开始位置,如下图
---|---L------|-----R-----
---|---L-----|^-----r-----
^是l的位置
这样每次l都是向块内移动的r每次都是向右移动的,就保证了区间的递增性
如果L和R都是在同一个块内怎么办,,
for暴力计算!!!!
观察l,每次移动到应该查询的位置(L),然后计算完答案后,再移动回去(下一块的开始位置)
这样,就是回滚莫队 了,可以明显看到l是滚来~滚去~的
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
map vis;
int a[maxn],n,q,base;
int val[maxn],cnt[maxn],block[maxn];
struct node{
int l,r,id;
bool operator < (const node &b)const{
return block[l]^block[b.l]?block[l]Q[i].l)Add(--ql);//滚来~~
out[Q[i].id] = ans;
while(ql