hdu2871 Memory Control(线段树 区间合并)

题意

N个空间,M次操作

有以下几种操作:

①New len

开辟len个单位的空间,

如果能开输出New at 位置,

否则输出Reject New

②Free pos

删除pos这个位置所在的那个块

如果能删输出Free from 块首 to 块尾,

否则输出Reject Free

③Get num

输出从左到右的第num块,

如果存在输出Get at 块首

否则输出Reject Get

④Reset 

清空所有块,

并输出Reset Now

思路来源

https://blog.csdn.net/wbb1997/article/details/80598591

题解

和poj3667Hotel区间合并很像

此外,加上了一个vector的insert和erase操作,

每次找pos所在块时,二分块的位置

我们每新建一个块,就按l增序加到vector里,

然后动态维护这个vector即可

坑点

tm行末要加一行回车???

好吧像我这种搜完题解就回来背着敲的人自然是眼瞎

电子竞技不需要视力

代码

#include
#include
#include
#include 
#include
using namespace std;
typedef long long ll;
typedef pair P;
const int maxn=5e4+10;
int n,m;
char op[10];
int L[5*maxn],R[5*maxn],dat[5*maxn],cov[5*maxn];
vector

block; //p编号代表的这段区间 //L代表左起最长 R代表右起最长 dat代表区间最长不论位置 //cov代表标记 -1不需要操作 0全赋空 1全赋满 void build(int p,int l,int r) { dat[p]=L[p]=R[p]=r-l+1; cov[p]=-1; if(l==r)return; int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); } void pushdown(int p,int l,int r) { if(cov[p]!=-1) { int mid=(l+r)>>1; cov[p<<1]=cov[p<<1|1]=cov[p]; dat[p<<1]=L[p<<1]=R[p<<1]=cov[p]?0:mid-l+1;//0全赋空 1全赋满 dat[p<<1|1]=L[p<<1|1]=R[p<<1|1]=cov[p]?0:r-mid;//0全赋空 1全赋满 cov[p]=-1; } } void pushup(int p,int l,int r) { int mid=(l+r)>>1; dat[p]=max(dat[p<<1],dat[p<<1|1]); dat[p]=max(dat[p],R[p<<1]+L[p<<1|1]); L[p]=L[p<<1]; if(L[p<<1]==mid-l+1)L[p]+=L[p<<1|1]; R[p]=R[p<<1|1]; if(R[p<<1|1]==r-mid)R[p]+=R[p<<1]; } void update(int p,int l,int r,int ql,int qr,int c) { if(ql<=l&&r<=qr) { dat[p]=L[p]=R[p]=c?0:r-l+1; cov[p]=c; return; } pushdown(p,l,r); int mid=(l+r)>>1; if(ql<=mid)update(p<<1,l,mid,ql,qr,c); if(qr>mid)update(p<<1|1,mid+1,r,ql,qr,c); pushup(p,l,r); } int ask(int p,int l,int r,int num) { if(l==r)return l;//左对齐之后递归到端点 pushdown(p,l,r); int mid=(l+r)>>1; if(dat[p<<1]>=num)return ask(p<<1,l,mid,num);//左 else if(R[p<<1]+L[p<<1|1]>=num)return mid-R[p<<1]+1;//拼凑 else return ask(p<<1|1,mid+1,r,num);//右 } int find(int pos) { int l=0,r=block.size()-1; while(l<=r) { int mid=(l+r)>>1; if(block[mid].first<=pos&&block[mid].second>=pos)return mid; else if(block[mid].first>pos)r=mid-1; else if(block[mid].second

 

你可能感兴趣的:(线段树,区间合并,线段树(权值线段树)/树状数组)