首先,显然每个区间的最长连续子区间要么在左孩子里,要么在右孩子里,要么跨越两个孩子。于是我们可以对每个区间维护如下信息ll(left long),rl(rigth long),ml(mid long)分别表示前缀最长长度,后缀最长长度,中间的最长区间长度,并维护即可。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<stack> 11 #include<string> 12 13 using namespace std; 14 15 struct Tree{ 16 int l,r; 17 int ll,rl,ml; 18 }; 19 20 int n,m; 21 Tree T[400007]; 22 23 void buildtree(int now,int l,int r){ 24 T[now].ll=T[now].rl=T[now].ml=r-l+1; 25 T[now].l=l; 26 T[now].r=r; 27 if (l==r) return; 28 buildtree(now<<1,l,(l+r)>>1); 29 buildtree((now<<1)|1,((l+r)>>1)+1,r); 30 } 31 32 void update(int now,int aim,int val){ 33 if (T[now].l==T[now].r){ 34 T[now].ll=T[now].rl=T[now].ml=val; 35 return; 36 } 37 int mid=(T[now].l+T[now].r)>>1; 38 if (aim<=mid) update(now<<1,aim,val); 39 else update((now<<1)|1,aim,val); 40 T[now].ll=T[now<<1].ll; 41 T[now].rl=T[(now<<1)|1].rl; 42 if (T[now<<1].ll==(T[now<<1].r-T[now<<1].l+1)) T[now].ll=T[now].ll+T[(now<<1)|1].ll; 43 if (T[(now<<1)|1].rl==T[(now<<1)|1].r-T[(now<<1)|1].l+1) T[now].rl+=T[now<<1].rl; 44 T[now].ml=max(T[now<<1].ml,T[(now<<1)|1].ml); 45 T[now].ml=max(T[now].ml,T[now<<1].rl+T[(now<<1)|1].ll); 46 } 47 48 int query(int now,int aim){ 49 if (T[now].l==T[now].r || T[now].ml==0 || T[now].ml==T[now].r-T[now].l+1){ 50 return T[now].ml; 51 } 52 int mid=(T[now].l+T[now].r)>>1; 53 if (aim<=mid){ 54 if (aim>=T[now<<1].r-T[now<<1].rl+1) 55 return query(now<<1,aim)+query((now<<1)|1,mid+1); 56 else 57 return query(now<<1,aim); 58 } 59 else{ 60 if (aim<=T[(now<<1)|1].l+T[(now<<1)|1].ll-1) 61 return query((now<<1)|1,aim)+query(now<<1,mid); 62 else 63 return query((now<<1)|1,aim); 64 } 65 } 66 67 int main(){ 68 scanf("%d%d",&n,&m); 69 buildtree(1,1,n); 70 for (int cas=1;cas<=m;cas++){ 71 int f,x; 72 scanf("%d%d",&f,&x); 73 if (f==0){ 74 update(1,x,0); 75 } 76 if (f==1){ 77 update(1,x,1); 78 } 79 if (f==2){ 80 printf("%d ",query(1,x)); 81 } 82 checktree(1,1,n); 83 } 84 return 0; 85 } 86 /* 87 5 3 88 2 2 89 0 3 90 2 2 91 92 5 5 93 2 2 94 0 3 95 2 2 96 1 3 97 2 2 98 */