标签:
http://poj.org/problem?id=3667
宾馆有n个房间编号1到n都为空房,然后m个询问,当输入第一个为1的时候,代表要住进x个连续的房间,输入房间号最小的数,如果没有
输出0.当第一个数为2的时候,将从x号到y号的房间又变为空房,没有输出
与区间有关想想用线段树可不可以解决,就像是涂颜色一样把住与未住的房间号做个标记就行,问题是这里给的是区间的长度,并不是
具体的区间,处理起来比较麻烦 还要去找合适的区间,所以引入了len1表示某区间可用的最大长度,len2表示从区间左端开始可用的最大长度,
len3表示从区间右端开始可用的最大长度,最后更新维护一下
code
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 struct point { 5 int l,r; 6 int len1,len2,len3; 7 int mark; //lazy判断 8 }; 9 point tree[50001*4]; 10 void build(int i,int left,int right) 11 { 12 tree[i].l=left,tree[i].r=right; 13 tree[i].len1=tree[i].len2=tree[i].len3=tree[i].r-tree[i].l+1;//长度开始都为区间长度 14 tree[i].mark=0; 15 if (left==right) return; 16 int mid=(left+right)/2; 17 build(i*2,left,mid); 18 build(i*2+1,mid+1,right); 19 } 20 void update(int i,int left,int right,int val) 21 { 22 if (tree[i].l==left&&tree[i].r==right) 23 { 24 int e; 25 tree[i].mark=val; 26 if (val) e=0; //如果占领了,区间长度就为0了 27 else e=tree[i].r-tree[i].l+1; 28 tree[i].len1=tree[i].len2=tree[i].len3=e; 29 return; 30 } 31 if (tree[i].mark!=-1) 32 { 33 int q=tree[i].mark,e,r; 34 tree[i*2].mark=tree[i*2+1].mark=tree[i].mark; 35 tree[i].mark=-1; 36 if (q) e=0,r=0; 37 else 38 { 39 e=tree[i*2].r-tree[i*2].l+1; 40 r=tree[i*2+1].r-tree[i*2+1].l+1; 41 } 42 tree[i*2].len1=tree[i*2].len2=tree[i*2].len3=e; 43 tree[i*2+1].len1=tree[i*2+1].len2=tree[i*2+1].len3=r; 44 } 45 int mid=(tree[i].r+tree[i].l)/2; 46 if(left>mid) update(i*2+1,left,right,val); 47 else if(right<=mid) update(i*2,left,right,val); 48 else 49 { 50 update(i*2,left,mid,val); 51 update(i*2+1,mid+1,right,val); 52 } 53 int tmp = max(tree[i*2].len1,tree[i*2+1].len1); 54 tree[i].len1=max(tmp,tree[i*2].len3 + tree[i*2+1].len2); 55 tree[i].len2=tree[i*2].len2; 56 tree[i].len3=tree[i*2+1].len3; 57 if(tree[i*2].len1 == tree[i*2].r-tree[i*2].l+1)//将子区间的len2和len3维护 58 tree[i].len2+=tree[i*2+1].len2; 59 if(tree[i*2+1].len1 == tree[i*2+1].r-tree[i*2+1].l+1) 60 tree[i].len3+=tree[i*2].len3; 61 return ; 62 } 63 int find(int i,int len) 64 { 65 if (tree[i].l==tree[i].r&&len==1) return tree[i].l; 66 if (tree[i].mark!=-1) 67 { 68 int q=tree[i].mark,e,r; 69 tree[i*2].mark=tree[i*2+1].mark=tree[i].mark; 70 tree[i].mark=-1; 71 if (q) e=0,r=0; 72 else 73 { 74 e=tree[i*2].r-tree[i*2].l+1; 75 r=tree[i*2+1].r-tree[i*2+1].l+1; 76 } 77 tree[i*2].len1=tree[i*2].len2=tree[i*2].len3=e; 78 tree[i*2+1].len1=tree[i*2+1].len2=tree[i*2+1].len3=r; 79 } 80 if (tree[i*2].len1>=len) return find(i*2,len); 81 else if (tree[i*2].len3+tree[i*2+1].len2>=len) return (tree[i*2].r-tree[i*2].len3+1); 82 else if (tree[i*2+1].len1>=len) return find(i*2+1,len); 83 else return 0; 84 } 85 int main() 86 { 87 int n,m,x,y,z,w; 88 while (~scanf("%d %d",&n,&m)) 89 { 90 build(1,1,n); 91 while (m--) 92 { 93 scanf("%d",&x); 94 if (x==1) 95 { 96 scanf("%d",&y); 97 w=find(1,y); 98 printf("%d\n",w); 99 if (w) update(1,w,w+y-1,1); 100 } 101 if (x==2) 102 { 103 scanf("%d %d",&y,&z); 104 update(1,y,y+z-1,0); 105 } 106 } 107 } 108 return 0; 109 }
标签:
原文地址:http://www.cnblogs.com/JJCHEHEDA/p/4729322.html