您的位置:首页 > 其它

hdu 2871 线段树 成段更新+STL

2012-10-19 12:35 337 查看
/*
分析本题和我前几天做的题目非常类似,但模拟过程需要用vector 来处理。。。貌似我又弱在了这个stl 身上了。。整了2个小时的stl.........
题目分析:题目有4个操作:Reset指清空整个线段树,即题目所说的清空整个内存块;
New N就是申请N个最靠左边的连续内存块,
Free x操作是释放包含x的连续内存块,
Get x,就是获得第x个内存块的起始节点
我们用vector存取所有申请过的空间,删除所有释放的空间,查询第n个区间也是非常easy。
关键在于vector可以在中间进行查询,增减!!这也是该题所要求的一个一个知识点。
还是对stl 不熟

*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=55555;
int lmax[maxn<<2],rmax[maxn<<2],mmax[maxn<<2],col[maxn<<2],n,m;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
char op[10];
struct node///优先队列
{
int l,r;
bool operator < (const node &cmp) const
{
return l<cmp.l;
}
} ;
void pushup(int rt,int l,int r)
{
int mid=(l+r)>>1;
lmax[rt]=lmax[rt<<1];
rmax[rt]=rmax[rt<<1|1];
mmax[rt]=max(rmax[rt<<1]+lmax[rt<<1|1],max(mmax[rt<<1],mmax[rt<<1|1]));
if(lmax[rt<<1]==mid-l+1) lmax[rt]+=lmax[rt<<1|1];
if(rmax[rt<<1|1]==r-mid) rmax[rt]+=rmax[rt<<1];
}
void build(int rt,int l,int r)
{
lmax[rt]=rmax[rt]=mmax[rt]=(r-l+1);
col[rt]=-1;
if(l==r)return;
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt,l,r);
}
void pushdown(int rt,int l,int r)
{
if(col[rt]!=-1)
{
col[rt<<1]=col[rt<<1|1]=col[rt];
int mid=(l+r)>>1;
if(col[rt]==1)///已被占用
{
lmax[rt<<1]=rmax[rt<<1]=lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1]=mmax[rt<<1|1]=0;
}
else
{
lmax[rt<<1]=rmax[rt<<1]=mmax[rt<<1]=mid-l+1;
lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1|1]=r-mid;
}
col[rt]=-1;
}
}
void updata(int rt,int l,int r,int L,int R,int val)
{
if(L<=l&&r<=R)
{
col[rt]=val;
lmax[rt]=rmax[rt]=mmax[rt]=(r-l+1)*(val^1);
return ;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if(mid>=L)updata(lson,L,R,val);
if(mid<R)updata(rson,L,R,val);
pushup(rt,l,r);
}
int query(int rt,int l,int r,int len)
{
if(mmax[rt]<len) return -1;
if(lmax[rt]>=len)return l;
pushdown(rt,l,r);
int mid=(l+r)>>1;
if(mmax[rt<<1]>=len)return query(lson,len);
if(rmax[rt<<1]+lmax[rt<<1|1]>=len) return mid-rmax[rt<<1]+1;
return query(rson,len);
}
int main()
{
int i,j,res,tmp;
char s[10];
vector<node>V;
while(scanf("%d %d",&n,&m)!=EOF)
{
build(1,1,n);
V.clear();
while(m--)
{
scanf("%s",s);
if(s[0] == 'N')
{
scanf("%d",&res);
if(mmax[1] < res)
puts("Reject New");
else
{
int ret= query(1,1,n,res);
printf("New at %d\n",ret);
updata(1,1,n,ret,ret+res-1,1);
node p;
p.l = ret;
p.r = ret+res-1;
vector<node>::iterator it;
it = upper_bound(V.begin(),V.end(),p);
V.insert(it,p);
}
}
else if(s[0] == 'F')
{
scanf("%d",&res);
node p;
p.l = res;
p.r = res;
vector<node>::iterator it;
it = upper_bound(V.begin(),V.end(),p);
int tmp = it - V.begin() - 1;
if(tmp == -1 || V[tmp].r<res)
puts("Reject Free");
else
{
printf("Free from %d to %d\n", V[tmp].l, V[tmp].r);
updata(1,1,n,V[tmp].l,V[tmp].r,0);
V.erase(V.begin()+tmp);
}
}
else if(s[0] == 'G')
{
scanf("%d",&res);
if(res > V.size())
puts("Reject Get");
else
printf("Get at %d\n",V[res-1].l);
}
else if(s[0] == 'R')
{
updata(1,1,n,1,n,0);
V.clear();
puts("Reset Now");
}
}
printf("\n");
}
return 0;
}

/*
6 16
New 2
New 5
New 2
New 2
Free 3
Get 1
Get 2
Get 3
Free 3
Reset
New 2
New 5
New 2
New 2
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: