Hotel
大体分析:
题意:从最左找连续空间,是否能找到。
解法:同poj1823。
//是1823的加强版,但是提交记录也是呵呵了。
//多的一个操作就是查询操作了。
具体分析
更新操作同poj1823
查询操作:
1. 先判断是都存在
2. 如果存在,左儿子中有就递归找左儿子
3. 如果左儿子的有连续+有儿子的左连续空间有,那就返回位置
4. 否则,递归寻找右儿子
//线段树真是奇妙,很多更新、查询操作都很巧妙
参考代码
- #include<iostream>
- #include<cstring>
- #include <algorithm>
- #include<cstdlib>
- #include<vector>
- #include<cmath>
- #include<stdlib.h>
- #include<iomanip>
- #include<list>
- #include<deque>
- #include<map>
- #include <stdio.h>
- #include <queue>
-
- #define maxn 201000+5
-
- #define inf 0x3f3f3f3f
- #define INF 0x3FFFFFFFFFFFFFFFLL
- #define rep(i,n) for(i=0;i<n;i++)
- #define reP(i,n) for(i=1;i<=n;i++)
-
- #define ull unsigned long long
- #define ll long long
- #define LL(x) x<<1
- #define RR(x) x<<1|1
-
- #define cle(a) memset(a,0,sizeof(a))
-
- using namespace std;
- struct node{
- int l,r,lsum,rsum,msum;
- int flag;
- int mid(){
- return (l+r)>>1;
- }
- void init(){
- lsum=rsum=msum=(r-l+1)*flag;
- }
- }tree[maxn*4];
- void build(int rt,int l,int r){
- tree[rt].l=l,tree[rt].r=r,tree[rt].flag=1;
- tree[rt].init();
- if(l==r)return;
- int mid=tree[rt].mid();
- build(LL(rt),l,mid),build(RR(rt),mid+1,r);
- }
- void update(int rt,int l,int r,int flag){
- if(l<=tree[rt].l&&r>=tree[rt].r){
- tree[rt].flag=flag;tree[rt].init();return;
- }
- if(tree[rt].flag!=-1){
- tree[LL(rt)].flag=tree[RR(rt)].flag=tree[rt].flag;
- tree[LL(rt)].init();tree[RR(rt)].init();tree[rt].flag=-1;
- }
- int mid=tree[rt].mid();
- if(r<=mid)update(LL(rt),l,r,flag);
- else if(l>mid)update(RR(rt),l,r,flag);
- else {
- update(LL(rt),l,mid,flag);update(RR(rt),mid+1,r,flag);
- }
- if(tree[LL(rt)].lsum==tree[LL(rt)].r-tree[LL(rt)].l+1)tree[rt].lsum=tree[LL(rt)].lsum+tree[RR(rt)].lsum;
- else tree[rt].lsum=tree[LL(rt)].lsum;
- if(tree[RR(rt)].rsum==tree[RR(rt)].r-tree[RR(rt)].l+1)tree[rt].rsum=tree[LL(rt)].rsum+tree[RR(rt)].rsum;
- else tree[rt].rsum=tree[RR(rt)].rsum;
- tree[rt].msum=max(max(tree[LL(rt)].msum,tree[RR(rt)].msum),tree[LL(rt)].rsum+tree[RR(rt)].lsum);
- }
- int query(int rt,int l,int r,int w)
- {
- if(l==r)return l;
- if(tree[rt].flag!=-1){
- tree[LL(rt)].flag=tree[RR(rt)].flag=tree[rt].flag;
- tree[LL(rt)].init();tree[RR(rt)].init();tree[rt].flag=-1;
- }
- int mid=tree[rt].mid();
- if(tree[LL(rt)].msum>=w) return query(LL(rt),l,mid,w);
- else if(tree[LL(rt)].rsum+tree[RR(rt)].lsum>=w)return mid-tree[LL(rt)].rsum+1;
- else return query(RR(rt),mid+1,r,w);
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
-
- #endif
- int n,m;
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- build(1,1,n);
- int i;
- rep(i,m){
- int temp,x,y;
- scanf("%d",&temp);
- if(temp==1){
- scanf("%d",&x);
- if(tree[1].msum<x)printf("%d\n",0);
- else {
- int be=query(1,1,n,x);
- printf("%d\n",be);
- update(1,be,be+x-1,0);
- }
- }
- else{
- scanf("%d%d",&x,&y);
- update(1,x,x+y-1,1);
- }
- }
- }
- return 0;
- }