poj 3667 线段树

题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
2 a b:将[a,a+b-1]的房间清空
思路:记录区间中最长的空房间
线段树操作:update:区间替换 query:询问满足条件的最左断点
Sample Input
10 6        10个房间 6次询问
1 3         找3个房间
1 3
1 3
1 3
2 5 5       将5~5+5-1的房间清空
1 6
Sample Output
1
4
7
0
5

不是很好写

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 using namespace std;
  9 #define MOD 1000000007
 10 const int INF=0x3f3f3f3f;
 11 const double eps=1e-5;
 12 #define cl(a) memset(a,0,sizeof(a))
 13 #define ts printf("*****
");
 14 #define lson l,mid,rt<<1
 15 #define rson mid+1,r,rt<<1|1
 16 #define root 1,n,1
 17 #define mid ((l+r)>>1)
 18 const int MAXN=60000;
 19 int n,m,t,Min,tt;
 20 int msum[MAXN<<2],col[MAXN<<2],hash[MAXN],lsum[MAXN<<2],rsum[MAXN<<2];
 21 void build(int l,int r,int rt)
 22 {
 23     msum[rt]=lsum[rt]=rsum[rt]=r-l+1;
 24     col[rt]=-1;
 25     if (l==r) return ;
 26     build(lson);
 27     build(rson);
 28 }
 29 void pushup(int rt,int m)
 30 {
 31     lsum[rt]=lsum[rt<<1];
 32     rsum[rt]=rsum[rt<<1|1];
 33     if(lsum[rt]==(m-(m>>1)))    lsum[rt]+=lsum[rt<<1|1];
 34     if(rsum[rt]==(m>>1))    rsum[rt]+=rsum[rt<<1];
 35     msum[rt]=max(lsum[rt<<1|1]+rsum[rt<<1],max(msum[rt<<1],msum[rt<<1|1]));
 36 }
 37 void pushdown(int rt,int m)
 38 {
 39     if(col[rt]!=-1)
 40     {
 41         col[rt<<1]=col[rt<<1|1]=col[rt];
 42         msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=col[rt]?0:(m-(m>>1));
 43         msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=col[rt]?0:(m>>1);
 44         col[rt]=-1;
 45     }
 46 }
 47 void update(int L,int R,int val,int l,int r,int rt)
 48 {
 49     if(l>=L&&r<=R)
 50     {
 51         msum[rt]=lsum[rt]=rsum[rt]=val?0:r-l+1;
 52         col[rt]=val;
 53         return;
 54     }
 55     pushdown(rt,r-l+1);
 56     if(L<=mid) update(L,R,val,lson);
 57     if(R>mid) update(L,R,val,rson);
 58     pushup(rt,r-l+1);
 59 }
 60 int query(int val,int l,int r,int rt){
 61     if(l==r)
 62     {
 63         return l;
 64     }
 65     pushdown(rt,r-l+1);
 66     if(msum[rt<<1]>=val) return query(val,lson);
 67     else if(rsum[rt<<1]+lsum[rt<<1|1]>=val) return ((l+r)>>1)-rsum[rt<<1]+1;
 68     return query(val,rson);
 69 }
 70 
 71 int main()
 72 {
 73     #ifndef ONLINE_JUDGE
 74     freopen("1.in","r",stdin);
 75     #endif
 76     scanf("%d%d",&n,&m);
 77     build(root);
 78     while(m--)
 79     {
 80         int op,a,b;
 81         scanf("%d",&op);
 82         if(op == 1)
 83         {
 84             scanf("%d",&a);
 85             if(msum[1]<a) puts("0");
 86             else
 87             {
 88                 int p=query(a,root);
 89                 printf("%d
",p);
 90                 update(p,p+a-1,1,root);
 91             }
 92         }
 93         else
 94         {
 95             scanf("%d%d",&a,&b);
 96             update(a,a+b-1,0,root);
 97         }
 98     }
 99     return 0;
100 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4448817.html