BZOJ4358 : permu
把询问看成二维点,建立kd-tree,每个点维护一个计数器。
从1到n依次加入每个数,每次加入一个数时,对于所有包含它的询问,计数器加一,对于其它询问,计数器置0。
那么每个询问的答案就是计数器的历史最大值,可以通过打标记实现。
时间复杂度$O(n\sqrt{m})$。
#include<cstdio> #include<algorithm> const int N=50010,inf=-1,BUF=2000000; int n,m,i,x,id[N],root,cmp_d,X,a[N];char Buf[BUF],*buf=Buf; inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} struct node{ int D[2],l,r,Max[2],Min[2]; int m,d,e,hm,hd,he; }t[N]; inline bool cmp(const node&a,const node&b){return a.D[cmp_d]<b.D[cmp_d];} inline void Max(int&a,int b){if(a<b)a=b;} inline void Min(int&a,int b){if(a>b)a=b;} inline void up(int x){ id[t[x].e]=x,t[x].e=t[x].he=inf; if(t[x].l){ Max(t[x].Max[0],t[t[x].l].Max[0]); Min(t[x].Min[0],t[t[x].l].Min[0]); Max(t[x].Max[1],t[t[x].l].Max[1]); Min(t[x].Min[1],t[t[x].l].Min[1]); } if(t[x].r){ Max(t[x].Max[0],t[t[x].r].Max[0]); Min(t[x].Min[0],t[t[x].r].Min[0]); Max(t[x].Max[1],t[t[x].r].Max[1]); Min(t[x].Min[1],t[t[x].r].Min[1]); } } int build(int l,int r,int D){ int mid=(l+r)>>1; cmp_d=D,std::nth_element(t+l+1,t+mid+1,t+r+1,cmp); t[mid].Max[0]=t[mid].Min[0]=t[mid].D[0]; t[mid].Max[1]=t[mid].Min[1]=t[mid].D[1]; if(l!=mid)t[mid].l=build(l,mid-1,!D); if(r!=mid)t[mid].r=build(mid+1,r,!D); return up(mid),mid; } inline void hdoa(node&x,int v){ Max(x.hm,x.m+v); if(x.e>inf)Max(x.he,x.e+v);else Max(x.hd,x.d+v); } inline void hdoc(node&x,int v){Max(x.hm,v);Max(x.he,v);} inline void doa(node&x,int v){ Max(x.hm,x.m+=v); if(x.e>inf)Max(x.he,x.e+=v);else Max(x.hd,x.d+=v); } inline void doc(node&x,int v){Max(x.hm,x.m=v);Max(x.he,x.e=v);x.d=0;} inline void pb(node&x){ if(x.hd){ if(x.l)hdoa(t[x.l],x.hd); if(x.r)hdoa(t[x.r],x.hd);x.hd=0; } if(x.he>inf){ if(x.l)hdoc(t[x.l],x.he); if(x.r)hdoc(t[x.r],x.he); x.he=inf; } if(x.d){ if(x.l)doa(t[x.l],x.d); if(x.r)doa(t[x.r],x.d); x.d=0; }else if(x.e>inf){ if(x.l)doc(t[x.l],x.e); if(x.r)doc(t[x.r],x.e); x.e=inf; } } void change(node&x){ if(x.Min[0]>X||x.Max[1]<X){doc(x,0);return;} if(x.Max[0]<=X&&x.Min[1]>=X){doa(x,1);return;} pb(x); if(x.D[0]<=X&&x.D[1]>=X)Max(x.hm,++x.m);else x.m=0; if(x.l)change(t[x.l]); if(x.r)change(t[x.r]); } void dfs(node&x){ pb(x); if(x.l)dfs(t[x.l]); if(x.r)dfs(t[x.r]); } int main(){ fread(Buf,1,BUF,stdin),read(n),read(m); for(i=1;i<=n;i++)read(X),a[X]=i; for(i=1;i<=m;i++)read(t[i].D[0]),read(t[i].D[1]),t[i].e=i; root=build(1,m,1); for(i=1;i<=n;i++)X=a[i],change(t[root]); dfs(t[root]); for(i=1;i<=m;i++)printf("%d\n",t[id[i]].hm); return 0; }