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("*****\n");

 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\n",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 }

 

你可能感兴趣的:(poj)