| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
呵呵!/*
旅馆有N个连续的房间(从1到N编号),都是好的位置,现在每次都会来一群旅客,数量是Di 并且这些人,需要被安排在
这些房间中,但是所分配的房间必须是连续的,当然初始房间号 r 要尽可能小 同时又会有一部分人离开旅馆 参数
Xi 和Di这就代表 房间编号 Xi到 Xi+Di-1的房间现在空了。
输入数据,先输入两个整数 N M表示 房间的数量和要提问的数量
接下来的 M 行是提问 的问题
假如开头是 1 表示 后面有D个人要进房间,此时假如满足,你就要输出这个连续房间的位置
假如开头是 2 表示 后面有第
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std ;
#define N 50010
struct Node
{
int nleft;//左边连续的空房间数量
int nright;//右边连续的空房间数量
int maxn;//当前节点区间的空房间的最大数量
int flag;//更新标志位
};
Node seg_tree[N << 2];
//儿子节点更新给父亲节点
void push_up(int l, int r, int rt)
{
seg_tree[rt].nleft = seg_tree[rt<<1].nleft;
seg_tree[rt].nright = seg_tree[rt <<1|1].nright;
int mid = (l + r)>>1;
if(seg_tree[rt].nleft == mid - l + 1) seg_tree[rt].nleft += seg_tree[rt<<1|1].nleft;
if(seg_tree[rt].nright == r - mid) seg_tree[rt].nright += seg_tree[rt<<1].nright;
seg_tree[rt].maxn = max( max(seg_tree[rt<<1].maxn, seg_tree[rt<<1|1].maxn) , seg_tree[rt<<1].nright + seg_tree[rt<<1|1].nleft);
}
//父亲更新数据给孩子节点
void push_down(int l, int r, int rt)
{
if( seg_tree[rt].flag != -1)
{
seg_tree[rt<<1].flag = seg_tree[rt<<1|1].flag = seg_tree[rt].flag;//是否更新也要让孩子们知道
if( seg_tree[rt].flag == 1)//表示房间已经全满
{
//房间已经满了,说明最大房间数量是空
seg_tree[rt<<1].nleft = seg_tree[rt<<1].nright = seg_tree[rt<<1|1].nleft = seg_tree[rt<<1|1].nright = 0;
seg_tree[rt<<1].maxn = seg_tree[rt<<1|1].maxn = 0;
}
else
{
int mid = (l + r)>>1;
seg_tree[rt<<1].nleft = seg_tree[rt<<1].nright = seg_tree[rt<<1].maxn = mid - l +1;
seg_tree[rt<<1|1].nleft = seg_tree[rt<<1|1].nright = seg_tree[rt<<1|1].maxn = r - mid;
}
seg_tree[rt].flag = -1;
}
}
void update(int a, int L, int R, int l, int r, int rt)
{
//更新数据,就两种要求其一就是覆盖区间,其二就是取消覆盖区间
//假如在要被覆盖或者是范围内a就是标志
if(R>=r && L <= l)
{
if(a == 1)//表示房间已经满了
{
seg_tree[rt].nleft = seg_tree[rt].nright = 0 ;
seg_tree[rt].maxn = 0 ;
}
else
{
seg_tree[rt].nleft = seg_tree[rt].nright = r - l +1;
seg_tree[rt].maxn = r - l +1;
}
seg_tree[rt].flag = a;
return;
}
int mid = (l + r)>>1;
push_down(l,r,rt);
if( L<=mid)update(a,L,R,l,mid,rt<<1);
if(R>mid) update(a,L,R,mid+1,r,rt<<1|1);
push_up(l,r,rt);
}
int query(int x, int l, int r, int rt)
{
if(l == r)
{
return l;
}
int mid = (l +r)>>1;
push_down(l,r,rt);
if(seg_tree[rt<<1].maxn >=x) return query(x,l,mid,rt<<1);
if(seg_tree[rt<<1].nright + seg_tree[rt<<1|1].nleft >= x) return mid - seg_tree[rt<<1].nright +1 ;
return query(x,mid+1,r,rt<<1|1);
}
void build(int l ,int r, int rt)
{
seg_tree[rt].maxn = seg_tree[rt].nleft = seg_tree[rt].nright = r -l +1;
seg_tree[rt].flag = -1;
if(l == r)
{
return;
}
int mid = (l +r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
}
int n,m;
int main( )
{
while(scanf("%d%d",&n,&m) != EOF)
{
build(1,n,1);
int a,x;
for(int i = 0; i < m; i++)
{
scanf("%d",&a);
if(a == 1)
{
scanf("%d",&x);
if(seg_tree[1].maxn<x)
{
printf("0\n");
continue;
}
else
{
int tmp = query(x,1,n,1);
printf("%d\n",tmp);
update(1,tmp,tmp + x -1,1,n,1);
}
}
else
{
scanf("%d%d",&a,&x);
update(0,a,a+x-1,1,n,1);
}
}
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator