题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2871
【题意】
有
n
n
n 个连续单元的内存空间和
q
q
q 次操作,每次开辟的连续单元的内存称为
b
l
o
c
k
block
block,操作分
4
4
4 种
N
e
w
x
New \ \ x
New x
开辟一个新的
b
l
o
c
k
block
block,使它具有连续
x
x
x 单元的内存且要求起点最小.若无法开辟新
b
l
o
c
k
block
block 输出
"
R
e
j
e
c
t
N
e
w
"
"Reject \ New"
"Reject New",否则输出新
b
l
o
c
k
block
block 的起点.
F
r
e
e
x
Free \ \ x
Free x
表示释放
x
x
x 单元所在的
b
l
o
c
k
block
block ,若找不到该
b
l
o
c
k
block
block 输出
"
R
e
j
e
c
t
F
r
e
e
"
"Reject \ Free"
"Reject Free",否则输出该
b
l
o
c
k
block
block 的起点和终点.
G
e
t
x
Get \ \ x
Get x
表示找到从左到右的第
x
x
x 个
b
l
o
c
k
block
block,若不能找到输出
"
R
e
j
e
c
t
G
e
t
"
"Reject \ Get"
"Reject Get",否则输出该block的起点。
R
e
s
e
t
Reset
Reset
表示清空所有内存,输出
"
R
e
s
e
t
N
o
w
"
"Reset Now"
"ResetNow"
下标均从
1
1
1 开始
(
n
,
q
<
=
50000
)
(n,q<=50000)
(n,q<=50000)
【思路】
线段树区间合并,同时用vector来模拟当前占用的内存区间,利用二分快速更新
#include<bits/stdc++.h>
#define node tree[id]
#define lson tree[id<<1]
#define rson tree[id<<1|1]
using namespace std;
typedef pair<int,int> pii;
const int inf=2e9;
const int maxn=50005;
struct Tree{
int left,right,len;
int sum,sumL,sumR;
int lazy;
}tree[maxn<<2];
int n,q;
char op[10];
vector<pii> v;
vector<pii>::iterator it;
void pushup(int id){
node.sumL=lson.sumL;
if(lson.sumL==lson.len) node.sumL+=rson.sumL;
node.sumR=rson.sumR;
if(rson.sumR==rson.len) node.sumR+=lson.sumR;
node.sum=lson.sumR+rson.sumL;
if(lson.sum>node.sum) node.sum=lson.sum;
if(rson.sum>node.sum) node.sum=rson.sum;
}
void pushdown(int id){
if(node.lazy!=-1 && node.left!=node.right){
lson.lazy=node.lazy;
lson.sum=lson.sumL=lson.sumR=node.lazy?lson.len:0;
rson.lazy=node.lazy;
rson.sum=rson.sumL=rson.sumR=node.lazy?rson.len:0;
node.lazy=-1;
}
}
void build(int id,int le,int ri){
node.left=le;
node.right=ri;
node.len=ri-le+1;
node.sum=node.sumL=node.sumR=ri-le+1;
node.lazy=-1;
if(le==ri) return;
int mid=(le+ri)>>1;
build(id<<1,le,mid);
build(id<<1|1,mid+1,ri);
}
int query(int id,int val){
if(node.left==node.right){
return node.left;
}
pushdown(id);
if(lson.sum>=val) return query(id<<1,val);
else if(lson.sumR+rson.sumL>=val) return rson.left-lson.sumR;
else return query(id<<1|1,val);
}
void update(int id,int le,int ri,int val){
if(node.left==le && node.right==ri){
node.sum=node.sumL=node.sumR=val?node.len:0;
node.lazy=val;
return;
}
pushdown(id);
int mid=(node.left+node.right)>>1;
if(ri<=mid) update(id<<1,le,ri,val);
else if(le>mid) update(id<<1|1,le,ri,val);
else{
update(id<<1,le,mid,val);
update(id<<1|1,mid+1,ri,val);
}
pushup(id);
}
int main(){
while(scanf("%d%d",&n,&q)==2){
build(1,1,n);
v.clear();
while(q--){
scanf("%s",op);
if(!strcmp(op,"New")){
int x;
scanf("%d",&x);
if(tree[1].sum<x) puts("Reject New");
else{
int pos=query(1,x);
printf("New at %d\n",pos);
update(1,pos,pos+x-1,0);
it=upper_bound(v.begin(),v.end(),pii(pos,inf));
v.insert(it,pii(pos,pos+x-1));
}
}
else if(!strcmp(op,"Free")){
int x;
scanf("%d",&x);
it=upper_bound(v.begin(),v.end(),pii(x,inf));
if(it==v.begin()) puts("Reject Free");
else{
--it;
if(it->second<x) puts("Reject Free");
else{
printf("Free from %d to %d\n",it->first,it->second);
update(1,it->first,it->second,1);
v.erase(it);
}
}
}
else if(!strcmp(op,"Get")){
int x;
scanf("%d",&x);
--x;
if(x<0 || x>=v.size()) puts("Reject Get");
else printf("Get at %d\n",v[x].first);
}
else{
puts("Reset Now");
v.clear();
update(1,1,n,1);
}
}
puts("");
}
return 0;
}