一眼觉得是莫队,发现删除不是很好搞,于是上回滚莫队直接搞过
回滚莫队用于处理难以删除但是易于添加(其实易于删除难以添加也可以,但是没见过这样题-_-)的莫队,排序照常,如果左右端点在同一块直接暴力,这部分最多n sqrt n,否则把左端点在一块的一起处理,清空莫队,然后直接令莫队左端点在块尾,这部分n sqrtn,右端点照常走,这部分n sqrtn ,左端点每次走的时候记录更改了哪些量,走到地方记录完答案把修改回滚回去,这部分也是n sqrtn,所以复杂度还是根号的,但是把删除干掉了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<ctime>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<bitset>
#include<map>
using namespace std;
#define MAXN 100010
#define MAXM 100010
#define INF 1000000000
#define MOD 1000000007
#define ll long long
#define eps 1e-8
char xB[1<<15],*xS=xB,*xT=xB;
#define getc() (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)
inline int read()
{
int x=0,f=1;char xch=getc();
while(xch<'0'|xch>'9'){if(xch=='-')f=-1;xch=getc();}
while(xch>='0'&&xch<='9'){x=x*10+xch-'0';xch=getc();}
return x*f;
}
struct que{
int l;
int r;
int num;
int k;
friend bool operator <(que x,que y){
return x.k!=y.k?x.k<y.k:x.r<y.r;
}
};
int siz;
que q[MAXM];
int a[MAXN];
int cnt[MAXN];
ll ans[MAXN];
int num[MAXN];
int visc[MAXN];
ll ANS;
map<int,int>h;
int tls[MAXN],tln,mx;
int g[MAXN];
int n,m;
int L,R;
int T;
int *st[MAXN];
int stv[MAXN],tp;
ll *sta[MAXN];
ll stva[MAXN];
int tpa;
void roolback(){
while(tp){
(*st[tp])=stv[tp];
tp--;
}
while(tpa){
(*sta[tpa])=stva[tpa];
tpa--;
}
}
int main(){
int i,j;
n=read();
m=read();
for(i=1;i<=n;i++){
a[i]=read();
tls[++tln]=a[i];
}
sort(tls+1,tls+tln+1);
tls[0]=-INF;
for(i=1;i<=tln;i++){
if(tls[i]!=tls[i-1]){
h[tls[i]]=++mx;
g[mx]=tls[i];
}
}
for(i=1;i<=n;i++){
a[i]=h[a[i]];
}
siz=sqrt(n);
for(i=1;i<=m;i++){
q[i].l=read();
q[i].r=read();
q[i].k=(q[i].l-1)/siz+1;
q[i].num=i;
}
sort(q+1,q+m+1);
for(i=1;i<=m;i++){
if(q[i].k!=q[i-1].k){
//<<"^^^"<<endl;
T++;
L=siz*q[i].k+1;
R=L-1;
ANS=0;
}
//<<q[i].l<<'!'<<q[i].r<<endl;
//<<L<<' '<<R<<endl;
//<<cnt[2]<<"&"<<endl;
if(q[i].r<L){
//<<"@"<<endl;
ANS=0;
for(j=q[i].l;j<=q[i].r;j++){
if(visc[a[j]]!=T){
cnt[a[j]]=0;
}
visc[a[j]]=T;
cnt[a[j]]++;
if((ll)g[a[j]]*cnt[a[j]]>ANS){
ANS=(ll)g[a[j]]*cnt[a[j]];
}
}
ans[q[i].num]=ANS;
T++;
ANS=0;
continue ;
}
while(R<q[i].r){
//<<"#"<<endl;
R++;
if(visc[a[R]]!=T){
cnt[a[R]]=0;
}
visc[a[R]]=T;
cnt[a[R]]++;
if((ll)g[a[R]]*cnt[a[R]]>ANS){
ANS=(ll)g[a[R]]*cnt[a[R]];
}
}
while(L>q[i].l){
//<<"!"<<endl;
L--;
if(visc[a[L]]!=T){
cnt[a[L]]=0;
}
st[++tp]=&visc[a[L]];
stv[tp]=visc[a[L]];
visc[a[L]]=T;
st[++tp]=&cnt[a[L]];
stv[tp]=cnt[a[L]];
cnt[a[L]]++;
if((ll)g[a[L]]*cnt[a[L]]>ANS){
sta[++tpa]=&ANS;
stva[tpa]=ANS;
ANS=(ll)g[a[L]]*cnt[a[L]];
}
}
ans[q[i].num]=ANS;
roolback();
L=siz*q[i].k+1;
}
for(i=1;i<=m;i++){
printf("%lld\n",ans[i]);
}
return 0;
}
/*
5 5
2 2 2 1 2
4 4
1 1
3 4
1 1
1 5
*/