线段树——区间合并(模板题)

poj 3667

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cctype>
 5 using namespace std;
 6 #define lson l,m,rt<<1
 7 #define rson m+1,r,rt<<1|1
 8 
 9 const int maxn=55555;
10 
11 //c初始化为-1是因为传值的时候可能有两种情况,一种是清空的情况,另一种是
12 //住宿的情况,清空时借用0把下标传到子区间,而住宿的时候把1传到子区间
13 int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2];
14 int cover[maxn<<2];
15 //做区间永远>=右区间 
16 void Pushdown(int rt,int m){
17     if(cover[rt]!=-1){
18         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
19         msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=cover[rt]?0:m-(m>>1);
20         //这不就是直接等于m吗?不是,因为如果是0的话,就是0.
21         msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=cover[rt]?0:(m>>1);
22         cover[rt]=-1;
23     }
24 }
25 void Pushup(int rt,int m){
26     lsum[rt]=lsum[rt<<1];
27     rsum[rt]=rsum[rt<<1|1];
28     if(lsum[rt]==m-(m>>1)) lsum[rt]+=lsum[rt<<1|1];
29     if(rsum[rt]==(m>>1)) rsum[rt]+=rsum[rt<<1];
30     msum[rt]=max(lsum[rt<<1|1]+rsum[rt<<1],max(msum[rt<<1],msum[rt<<1|1]));
31 }
32 
33 void build(int l,int r,int rt){
34     msum[rt]=lsum[rt]=rsum[rt]=r-l+1;
35     cover[rt]=-1;
36     if(l==r) return;
37     int m=(l+r)>>1;
38     build(lson);
39     build(rson);
40 }
41 
42 int query(int w,int l,int r,int rt){
43     //之所以会直接返回1,是因为在输入进来的时候判了可以取吗?
44     //如果取不到直接都进不来
45     if(l==r) return 1;
46     Pushdown(rt,r-l+1);
47     int m=(l+r)>>1;
48     if(msum[rt<<1]>=w) return query(w,lson);
49     else if(rsum[rt<<1]+lsum[rt<<1|1]>=w) return m-rsum[rt<<1]+1;
50     return query(w,rson);
51 }
52 
53 void update(int L,int R,int c,int l,int r,int rt){
54     if(L<=l&&r<=R){
55         //如果全部都涵盖了,那么一定都更新
56         msum[rt]=lsum[rt]=rsum[rt]=c?0:r-l+1;
57         cover[rt]=c;
58         return;
59     }
60     Pushdown(rt,r-l+1);
61     int m=(l+r)>>1;
62     if(L<=m) update(L,R,c,lson);
63     if(m<R) update(L,R,c,rson);
64     Pushup(rt,r-l+1);
65 }
66 int main(){
67     int n,m;
68     scanf("%d%d",&n,&m);
69     build(1,n,1);
70     int op,a,b;
71     while(m--){
72         scanf("%d",&op);
73         if(op==1){
74             scanf("%d",&a);
75             if(msum[1]<a) printf("0\n");
76             else{
77                 int p=query(a,1,n,1);
78                 printf("%d\n",p );
79                 update(p,p+a-1,1,1,n,1);
80             }
81         }else{
82             scanf("%d%d",&a,&b);
83             update(a,a+b-1,0,1,n,1);
84         }
85     }
86     return 0;
87 }

 

posted @ 2019-07-30 15:36  Chuhanjing  阅读(172)  评论(0编辑  收藏  举报