您的位置:首页 > 其它

【POJ3667】Hotel(线段树)

2018-10-27 15:14 323 查看

题意:有n个依次编号的元素,要求维护以下两个操作:

1.询问整个数列中是否有长度>=x的连续的一段未被标记的元素,若无输出0,若有输出最小的开始编号ans并将[ans,ans+x-1]标记

2.将[x,x+y-1]其中的元素取消标记(如果有)

n,m<=5e4

思路:线段树区间合并

记录从左、右边开始最长连续长度,一段最长连续长度,以及标记状态

Pascal跑的比C++快……

1 #include<cstdio>
2 #include<cstring>
3 #include<string>
4 #include<cmath>
5 #include<iostream>
6 #include<algorithm>
7 #include<map>
8 #include<set>
9 #include<queue>
10 #include<vector>
11 using namespace std;
12 typedef long long ll;
13 typedef unsigned int uint;
14 typedef unsigned long long ull;
15 typedef pair<int,int> PII;
16 typedef vector<int> VI;
17 #define fi first
18 #define se second
19 #define MP make_pair
20 #define N   210000
21 #define M   7010
22 #define eps 1e-8
23 #define pi  acos(-1)
24 #define oo  1e9
25 #define MOD 10007
26
27 struct node
28 {
29     int l,r,a,s;
30 }t
;
31
32 void build(int l,int r,int p)
33 {
34     t

.l=t[p].r=t[p].s=r-l+1; 35 t[p].a=2; 36 if(l==r) return; 37 int mid=(l+r)>>1; 38 build(l,mid,p<<1); 39 build(mid+1,r,p<<1|1); 40 } 41 42 void pushdown(int l,int r,int p) 43 { 44 int ls=p<<1; int rs=ls+1; 45 int mid=(l+r)>>1; 46 if(t[p].a==1) 47 { 48 t[ls].l=t[ls].r=t[ls].s=t[rs].l=t[rs].r=t[rs].s=0; 49 t[ls].a=t[rs].a=1; 50 } 51 if(t[p].a==2) 52 { 53 t[ls].l=t[ls].r=t[ls].s=mid-l+1; 54 t[rs].l=t[rs].r=t[rs].s=r-mid; 55 t[ls].a=t[rs].a=2; 56 } 57 } 58 59 void pushup(int l,int r,int p) 60 { 61 int ls=p<<1; int rs=ls+1; 62 if(t[ls].a==2) t[p].l=t[ls].l+t[rs].l; 63 else t[p].l=t[ls].l; 64 if(t[rs].a==2) t[p].r=t[rs].r+t[ls].r; 65 else t[p].r=t[rs].r; 66 t[p].s=max(max(t[ls].s,t[rs].s),t[ls].r+t[rs].l); 67 if(t[ls].a==1&&t[rs].a==1) t[p].a=1; 68 else if(t[ls].a==2&&t[rs].a==2) t[p].a=2; 69 else t[p].a=3; 70 } 71 72 int query(int l,int r,int x,int p) 73 { 74 if(l==r) return l; 75 pushdown(l,r,p); 76 int ls=p<<1; 77 int rs=ls+1; 78 int mid=(l+r)>>1; 79 if(t[ls].s>=x) return query(l,mid,x,ls); 80 else if(t[ls].r+t[rs].l>=x) return mid-t[ls].r+1; 81 else return query(mid+1,r,x,rs); 82 } 83 84 void update(int l,int r,int x,int y,int v,int p) 85 { 86 if(x<=l&&r<=y) 87 { 88 t[p].a=v; 89 if(v==1) 90 { 91 t[p].l=t[p].r=t[p].s=0; 92 } 93 if(v==2) 94 { 95 t[p].l=t[p].r=t[p].s=r-l+1; 96 } 97 return; 98 } 99 if(t[p].a==v) return; 100 pushdown(l,r,p); 101 int mid=(l+r)>>1; 102 int ls=p<<1; 103 int rs=ls+1; 104 if(x<=mid) update(l,mid,x,y,v,ls); 105 if(y>mid) update(mid+1,r,x,y,v,rs); 106 pushup(l,r,p); 107 } 108 109 int main() 110 { 111 112 int n,m; 113 scanf("%d%d",&n,&m); 114 build(1,n,1); 115 for(int i=1;i<=m;i++) 116 { 117 int x; 118 scanf("%d",&x); 119 if(x==1) 120 { 121 int y; 122 scanf("%d",&y); 123 if(t[1].s<y) printf("0\n"); 124 else 125 { 126 int k=query(1,n,y,1); 127 printf("%d\n",k); 128 update(1,n,k,k+y-1,1,1); 129 } 130 } 131 else 132 { 133 int y,z; 134 scanf("%d%d",&y,&z); 135 update(1,n,y,y+z-1,2,1); 136 } 137 } 138 return 0; 139 } 140 141

1 var t:array[1..200000]of record
2                           l,r,s:longint;
3                          end;
4     tag:array[1..200000]of longint;
5     n,m,i,x,y,z,k:longint;
6
7 procedure build(l,r,p:longint);
8 var mid:longint;
9 begin
10  t[p].s:=r-l+1;
11  tag[p]:=2;
12  if l=r then exit;
13
14  mid:=(l+r)>>1;
15  build(l,mid,p<<1);
16  build(mid+1,r,p<<1+1);
17 end;
18
19 function max(x,y:longint):longint;
20 begin
21  if x>y then exit(x);
22  exit(y);
23 end;
24
25 procedure pushdown(l,r,p:longint);
26 var ls,rs,mid,len:longint;
27 begin
28  ls:=p<<1; rs:=ls+1;
29  mid:=(l+r)>>1;
30  if tag[p]=1 then
31  begin
32   t[ls].l:=0; t[ls].r:=0; t[ls].s:=0; tag[ls]:=1;
33   t[rs].l:=0; t[rs].r:=0; t[rs].s:=0; tag[rs]:=1;
34  end;
35  if tag[p]=2 then
36  begin
37   len:=mid-l+1;
38   t[ls].l:=len; t[ls].r:=len; t[ls].s:=len; tag[ls]:=2;
39   len:=r-(mid+1)+1;
40   t[rs].l:=len; t[rs].r:=len; t[rs].s:=len; tag[rs]:=2;
41  end;
42 end;
43
44 procedure pushup(l,r,p:longint);
45 var ls,rs:longint;
46 begin
47  ls:=p<<1; rs:=ls+1;
48  if tag[ls]=2 then t[p].l:=t[ls].l+t[rs].l
49   else t[p].l:=t[ls].l;
50  if tag[rs]=2 then t[p].r:=t[rs].r+t[ls].r
51   else t[p].r:=t[rs].r;
52  t[p].s:=max(t[ls].s,t[rs].s);
53  t[p].s:=max(t[p].s,t[ls].r+t[rs].l);
54  if (tag[ls]=1)and(tag[rs]=1) then tag[p]:=1
55   else if (tag[ls]=2)and(tag[rs]=2) then tag[p]:=2
56    else tag[p]:=3;
57 end;
58
59 function query(l,r,v,p:longint):longint;
60 var mid,ls,rs:longint;
61 begin
62  if l=r then exit(l);
63  pushdown(l,r,p);
64  ls:=p<<1; rs:=ls+1;
65  mid:=(l+r)>>1;
66  if t[ls].s>=v then query:=query(l,mid,v,p<<1)
67   else if t[ls].r+t[rs].l>=v then query:=mid-t[ls].r+1
68    else query:=query(mid+1,r,v,p<<1+1);
69 end;
70
71 procedure update(l,r,x,y,v,p:longint);
72 var mid,len:longint;
73 begin
74  if (l=x)and(r=y) then
75  begin
76   tag[p]:=v;
77   if v=1 then
78   begin
79    t[p].l:=0; t[p].r:=0; t[p].s:=0;
80   end;
81   if v=2 then
82   begin
83    len:=y-x+1;
84    t[p].l:=len; t[p].r:=len; t[p].s:=len;
85   end;
86   exit;
87  end;
88  if tag[p]=v then exit;
89  pushdown(l,r,p);
90  mid:=(l+r)>>1;
91  if (x>=l)and(y<=mid) then update(l,mid,x,y,v,p<<1)
92   else if (x>mid)and(y<=r) then update(mid+1,r,x,y,v,p<<1+1)
93    else
94    begin
95     update(l,mid,x,mid,v,p<<1);
96     update(mid+1,r,mid+1,y,v,p<<1+1);
97    end;
98  pushup(l,r,p);
99 end;
100
101
102 begin
103
104  readln(n,m);
105  build(1,n,1);
106  for i:=1 to m do
107  begin
108   read(x);
109   if x=1 then
110   begin
111    read(y);
112    if t[1].s<y then writeln(0)
113     else
114     begin
115      k:=query(1,n,y,1);
116      writeln(k);
117      update(1,n,k,k+y-1,1,1);
118     end;
119   end;
120   if x=2 then
121   begin
122    read(y,z);
123    update(1,n,y,y+z-1,2,1);
124   end;
125  end;
126
127 end.
[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: