cdoj 秋实大哥与战争

首先,显然每个区间的最长连续子区间要么在左孩子里,要么在右孩子里,要么跨越两个孩子。于是我们可以对每个区间维护如下信息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\n",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 */

 

posted @ 2015-06-06 00:50  鼠宝宝  阅读(162)  评论(0编辑  收藏  举报