poj3667 hotel(线段树区间合并)

http://poj.org/problem?id=3667

之前网络赛水过一道区间合并的题 当时是全靠运气试对的 。

昨天纠结了一晚上也没看出来哪错,改的都跟人家代码一样了还是不对,今天又重新敲了一遍,莫名的就对了,,

开两个数组分别存这个区间两端点的连续区间 再开一标记数组 用来更新 向上向下都要更新

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define N 50010
 7 int s[N<<2],kc[N<<2],lc[N<<2],rc[N<<2];
 8 void build(int l,int r,int w)
 9 {
10     s[w] = lc[w] = rc[w] = r-l+1;
11     kc[w] = -1;
12     if(l==r)
13     return ;
14     int m = (l+r)/2;
15     build(l,m,w<<1);
16     build(m+1,r,w<<1|1);
17 }
18 void pushdown(int w,int c)
19 {
20     if(kc[w]!=-1)
21     {
22         kc[w<<1] = kc[w<<1|1] = kc[w];
23         s[w<<1] = lc[w<<1] = rc[w<<1] = kc[w]?0:c-(c>>1);
24         s[w<<1|1] = lc[w<<1|1] = rc[w<<1|1] = kc[w]?0:c>>1;
25         kc[w] = -1;
26     }
27 }
28 void pushup(int w,int c)
29 {
30     lc[w] = lc[w<<1];
31     rc[w] = rc[w<<1|1];
32     if(lc[w]==c-(c>>1))
33     lc[w]+=lc[w<<1|1];
34     if(rc[w]==c>>1)
35     rc[w]+=rc[w<<1];
36     s[w] = max(rc[w<<1]+lc[w<<1|1],max(s[w<<1],s[w<<1|1]));//找出区间中最长的连续段
37 }
38 void update(int a,int b,int c,int l,int r,int w)
39 {
40     if(l>=a&&b>=r)
41     {
42         s[w] = lc[w] = rc[w] = c?0:r-l+1;
43         kc[w] = c;
44         return ;
45     }
46     pushdown(w,r-l+1);
47     int m = (l+r)>>1;
48     if(a<=m)
49     update(a,b,c,l,m,w<<1);
50     if(b>m)
51     update(a,b,c,m+1,r,w<<1|1);
52     pushup(w,r-l+1);
53 }
54 int query(int c,int l,int r,int w)
55 {
56     if(l==r)
57     return l;
58     pushdown(w,r-l+1);
59     int m = (l+r)>>1;
60     if(s[w<<1]>=c)
61     return query(c,l,m,w<<1);
62     else
63     if(rc[w<<1]+lc[w<<1|1]>=c)//中间段
64     return m-rc[w<<1]+1;
65     return query(c,m+1,r,w<<1|1);
66 }
67 int main()
68 {
69     int i,j,k,n,m,x,d;
70     cin>>n>>m;
71     build(1,n,1);
72     while(m--)
73     {
74         cin>>k;
75         if(k==1)
76         {
77             cin>>x;
78             if(s[1]<x)
79             printf("0\n");
80             else
81             {
82                 int p = query(x,1,n,1);
83                 cout<<p<<endl;
84                 update(p,p+x-1,1,1,n,1);//将这一段更新为已被占
85             }
86         }
87         else
88         {
89             cin>>x>>d;
90             update(x,x+d-1,0,1,n,1);//将这一段更新为空
91         }
92     }
93     return 0;
94 }

 

posted @ 2012-10-18 13:35  _雨  阅读(214)  评论(0编辑  收藏  举报