bzoj1593[Usaco2008 Feb]Hotel 旅馆*

bzoj1593[Usaco2008 Feb]Hotel 旅馆

题意:

给个长度为n的全为0的序列,m种操作,1 di表示求序列中最早出现的长度为di的值为0的连续子序列,并把这个连续子序列赋为1;2 xi,di表示将[xi,xi+di-1]置为0。n,m≤50000。

题解:

用一个线段树,维护三个值:最长为0连续子序列,最长为0后缀,最长为0前缀。然后注意一下合并就行了。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 150010
 7 using namespace std;
 8 
 9 inline int read(){
10     char ch=getchar(); int f=1,x=0;
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
13     return f*x;
14 }
15 int ls[maxn],rs[maxn],ms[maxn],len[maxn],tg[maxn],n,m;
16 void update(int x){
17     ms[x]=max(rs[x<<1]+ls[x<<1|1],max(ms[x<<1],ms[x<<1|1]));
18     ls[x]=(ms[x<<1]==len[x<<1])?len[x<<1]+ls[x<<1|1]:ls[x<<1];
19     rs[x]=(ms[x<<1|1]==len[x<<1|1])?len[x<<1|1]+rs[x<<1]:rs[x<<1|1];
20 }
21 void pushdown(int x){
22     if(len[x]>1){
23         if(tg[x]==0){
24             ms[x<<1]=ls[x<<1]=rs[x<<1]=len[x<<1]; tg[x<<1]=0;
25             ms[x<<1|1]=ls[x<<1|1]=rs[x<<1|1]=len[x<<1|1]; tg[x<<1|1]=0; tg[x]=-1;
26         }
27         if(tg[x]==1){
28             ms[x<<1]=ls[x<<1]=rs[x<<1]=0; tg[x<<1]=1;
29             ms[x<<1|1]=ls[x<<1|1]=rs[x<<1|1]=0; tg[x<<1|1]=1; tg[x]=-1;
30         }
31     }
32 }
33 void build(int x,int l,int r){
34     len[x]=r-l+1; tg[x]=-1; if(l==r){ls[x]=rs[x]=ms[x]=1; return;}
35     int mid=(l+r)>>1; build(x<<1,l,mid); build(x<<1|1,mid+1,r); update(x);
36 }
37 int query(int x,int l,int r,int v){
38     pushdown(x); if(ms[x]<v)return 0; int mid=(l+r)>>1;
39     if(ms[x<<1]>=v)return query(x<<1,l,mid,v); if(rs[x<<1]+ls[x<<1|1]>=v)return mid-rs[x<<1]+1;
40     return query(x<<1|1,mid+1,r,v);
41 }
42 void fill(int x,int l,int r,int ql,int qr){
43     pushdown(x);
44     if(ql<=l&&r<=qr){ms[x]=ls[x]=rs[x]=0; tg[x]=1; return;} int mid=(l+r)>>1;
45     if(ql<=mid)fill(x<<1,l,mid,ql,qr); if(mid<qr)fill(x<<1|1,mid+1,r,ql,qr);
46     update(x);
47 }
48 void clear(int x,int l,int r,int ql,int qr){
49     pushdown(x);
50     if(ql<=l&&r<=qr){ms[x]=ls[x]=rs[x]=len[x]; tg[x]=0; return;} int mid=(l+r)>>1;
51     if(ql<=mid)clear(x<<1,l,mid,ql,qr); if(mid<qr)clear(x<<1|1,mid+1,r,ql,qr);
52     update(x);
53 }
54 int main(){
55     n=read(); build(1,1,n); m=read();
56     inc(i,1,m){
57         int x=read();
58         if(x==1){int y=read(),z=query(1,1,n,y); printf("%d\n",z); if(z)fill(1,1,n,z,z+y-1);}
59         if(x==2){int y=read(),z=read(); clear(1,1,n,y,y+z-1);}
60     }
61     return 0;
62 }

 

20160926

posted @ 2016-09-26 21:48  YuanZiming  阅读(187)  评论(0编辑  收藏  举报