码迷,mamicode.com
首页 > 其他好文 > 详细

【POJ3667】Hotel(线段树)

时间:2018-10-27 16:08:56      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:and   class   begin   区间   var   record   down   can   unsigned   

题意:有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[N];
 31 
 32 void build(int l,int r,int p)
 33 {
 34     t[p].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.

 

【POJ3667】Hotel(线段树)

标签:and   class   begin   区间   var   record   down   can   unsigned   

原文地址:https://www.cnblogs.com/myx12345/p/9861324.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!