[bzoj4358] permu

  强行上莫队+线段树显然是会T的。

  如果莫队没有删除的转移的话...就可以用并查集代替线段树。

  所以按照一般姿势将询问排序好后,右端点照常,左端点每次从左端点所属块的末端开始跑,跑完后暴力撤回。

  复杂度还是O(m*n^0.5)

  为了能够撤回,并查集合并的时候,以临时增加的点为父亲。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int maxn=50233;
 8 struct zs{int l,r,id;}q[maxn];
 9 int fa[maxn],sz[maxn],mp[maxn],st[maxn],top;
10 int B[maxn],An[maxn];
11 int i,j,k,n,m,ans;
12 
13 int ra;char rx;
14 inline int read(){
15     rx=getchar(),ra=0;
16     while(rx<'0'||rx>'9')rx=getchar();
17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
18 }
19 
20 inline int getfa(int x){return fa[x]!=x?fa[x]=getfa(fa[x]):x;}
21 inline int get1(int x){while(fa[x]!=x)x=fa[x];return x;}
22 
23 inline void add(int x){
24     sz[x]=1;
25     int pre=getfa(x-1),aft=getfa(x+1);
26     if(sz[pre])sz[pre]+=sz[x],fa[x]=pre,x=pre;
27     if(sz[aft])sz[aft]+=sz[x],fa[x]=aft,x=aft;
28     if(sz[x]>ans)ans=sz[x];
29 }
30 inline void add2(int x){
31     sz[x]=1;
32     int pre=get1(x-1),aft=get1(x+1);
33     
34     if(sz[pre])
35         sz[x]+=sz[pre],fa[pre]=x,st[++top]=pre;
36     if(sz[aft])
37         sz[x]+=sz[aft],fa[aft]=x,st[++top]=aft;
38     if(sz[x]>ans)ans=sz[x];
39 }
40 
41 bool cmp(zs a,zs b){return B[a.l]<B[b.l]||(B[a.l]==B[b.l]&&a.r<b.r);}
42 
43 int main(){
44     n=read(),m=read();int kuai=(int)sqrt(n*1.2)+3;
45     for(i=1;i<=n;i++)mp[i]=read(),B[i]=(i+kuai-1)/kuai;
46     for(i=1;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].id=i;
47     sort(q+1,q+1+m,cmp);
48     int r,r1,now,tmp;
49     for(i=1;i<=m;){
50         for(r=i;B[q[r].l]==B[q[i].l];r++);r--;
51         r1=B[q[i].l]==B[n]?n:B[q[i].l]*kuai;
52         for(j=0;j<=n+1;j++)fa[j]=j,sz[j]=0;
53         ans=0,now=r1+1;
54         
55         for(j=i;j<=r;j++){
56             while(now<=q[j].r)add(mp[now++]);
57             tmp=ans,top=0;
58             for(k=q[j].l;k<=q[j].r&&k<=r1;k++)add2(mp[k]);
59             An[q[j].id]=ans;
60             while(top)fa[st[top]]=st[top],top--;
61             for(k=q[j].l;k<=q[j].r&&k<=r1;k++)fa[mp[k]]=mp[k],sz[mp[k]]=0;
62             ans=tmp;
63         }
64         i=r+1;
65     }
66     for(i=1;i<=m;i++)printf("%d\n",An[i]);
67 }
View Code

 

posted @ 2016-07-05 18:57  czllgzmzl  阅读(298)  评论(0编辑  收藏  举报