Consider Mo team, but we found this stuff only supports \ (ins \) (As for how support will revisit), does not support \ (del \) operation, we construct a just \ (ins \) is not \ ( del \) Mo team.
As we sort Mo team's method, the first keyword \ (l \) block is located, is the second key \ (r \) . So when drained order, certainly when \ (L \) block is located is the same, \ (R & lt \) monotonically increasing, so we \ (L \) be treated in the same block where the inquiry. Provided for the block \ (B \) , its end position \ (End \) , we first find the complete sorting of all of the array \ (L \) block is located is \ (B \) query \ (q_1 \) , \ (Q_2 \) ...... \ (q_k \) , then the inquiry must be continuous in the array, and their \ (r \) certainly monotonically.
Then ask these certainly are long like this:
Since \ (r \) monotonically increasing, then for \ (r \) us directly \ (ins \) just fine. For \ (l \) , due to the \ (l \) in blocks \ (B \) inside, so each of us to ask directly from the \ (end \) to the left of violence \ (ins \) on it.
As \ (ins \) operation, we consider disjoint-set maintenance. For each value inserted \ (the X-\) , we find it in the value field and put it separately and \ (x-1 \) and (x + 1 \) \ where disjoint-set to link (if not nonunion), the answer is all focused on the investigation and the biggest \ (size \) .
code show as below:
#include<bits/stdc++.h>
#define N 50010
using namespace std;
struct Question
{
int l,r,block,id;
}q[N];
int n,m,len,block,a[N],ed[N],ans,Ans[N],st[N],top;
int fa1[N],size[N];
int fa2[N],minn[N],maxn[N];
int find1(int x)
{
return fa1[x]==x?x:fa1[x]=find1(fa1[x]);
}
int find2(int x)
{
return fa2[x]==x?x:fa2[x]=find2(fa2[x]);
}
int get(int x)
{
return (x-1)/len+1;
}
bool operator < (Question a,Question b)
{
return a.block==b.block?a.r<b.r:a.l<b.l;
}
void add1(int u)
{
int v;
fa1[u]=u,size[u]=1;
if(v=find1(u-1))
fa1[v]=u,size[u]+=size[v];
if(v=find1(u+1))
fa1[v]=u,size[u]+=size[v];
ans=max(ans,size[u]);
}
void add2(int u,int &Ans)
{
int v;
st[++top]=u;
fa2[u]=u,minn[u]=maxn[u]=u;
if(v=find2(u-1))minn[u]=minn[v];
else if(v=find1(u-1)) minn[u]-=size[v];
if(v=find2(u+1))maxn[u]=maxn[v];
else if(v=find1(u+1)) maxn[u]+=size[v];
Ans=max(Ans,maxn[u]-minn[u]+1);
if(minn[u]!=u)fa2[minn[u]]=u,st[++top]=minn[u];
if(maxn[u]!=u)fa2[maxn[u]]=u,st[++top]=maxn[u];
}
int main()
{
scanf("%d%d",&n,&m);
block=len=sqrt(n);
while(block*len<n)block++;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1,edd=len;i<=block;i++,edd=min(edd+len,n))
ed[i]=edd;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].block=get(q[i].l),q[i].id=i;
}
sort(q+1,q+m+1);
for(int p=1,i=1;i<=m;i=p+1,p=i)
{
memset(fa1,0,sizeof(fa1));
ans=0;
while(q[i].block==q[p+1].block)p++;
int now=ed[q[i].block];
for(int j=i;j<=p;j++)
{
while(now<q[j].r)add1(a[++now]);
Ans[q[j].id]=ans;
for(int k=q[j].l;k<=min(q[j].r,ed[q[j].block]);k++)
add2(a[k],Ans[q[j].id]);
while(top)
fa2[st[top--]]=0;
}
}
for(int i=1;i<=m;i++)
printf("%d\n",Ans[i]);
return 0;
}