0
点赞
收藏
分享

微信扫一扫

HDOJ 4614 - Vases and Flowers/2013多校联合第二场D 区间更新线段树+二分


       题意:

                 有N个花瓶..每个花瓶至多放一朵花..每次的操作是1、从某个序号的花瓶开始..F朵花到空的花瓶..若后面的空花瓶不足F..则把剩下的花丢掉..当后面没有一个空花瓶..输出Can not put any one...2、把[ L,R ]范围内所有的花拿掉...并输出这个区间之前有多少花..

       题解:

                 用线段树的区间查询与更新来维护当前的情况...为了方便统计..对于一个花瓶..若空着的就为1..有花就为0...线段树中父亲节点和子节点的更新关系是求和...在进行操作1 x F时..先用二分+线段树query找出区间[ x,n ]空着的花瓶的最左与最右.. 再query统计这段里的空花瓶是否小于等于F..如果是大于了..那么再在这个区间内二分+线段树query找出最终最右的位置..确定了位置后..update更新这个区间都为0..在进行操作2 l r 时..就直接query得出 [ l , r ] 有多少个空的...(r-l+1)-query就是所要的输出..再更新 [ l , r ] 区间都为1...

                 有个很恶心的地方...F居然可以为0...根据题意..输出Can not put any one..


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#define ll long long
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 50005
#define MAXM 50005
using namespace std;
int sum[MAXN<<2],col[MAXN<<2],n;
void PushDown(int len,int now)
{
if (col[now]==-1) return;
col[now<<1]=col[(now<<1)|1]=col[now];
sum[now<<1]=(len-(len>>1))*col[now];
sum[(now<<1)|1]=(len>>1)*col[now];
col[now]=-1;
return;
}
void update(int L,int R,int c,int l,int r,int now)
{
if (L<=l && R>=r)
{
sum[now]=(r-l+1)*c;
col[now]=c;
return;
}
PushDown(r-l+1,now);
int mid=(r+l)>>1;
if (L<=mid) update(L,R,c,l,mid,now<<1);
if (R>mid) update(L,R,c,mid+1,r,(now<<1)|1);
sum[now]=sum[now<<1]+sum[(now<<1)|1];
return;
}
int query(int L,int R,int l,int r,int now)
{
if (L<=l && R>=r) return sum[now];
PushDown(r-l+1,now);
int ans=0,mid=(r+l)>>1;
if (L<=mid) ans+=query(L,R,l,mid,now<<1);
if (R>mid) ans+=query(L,R,mid+1,r,(now<<1)|1);
return ans;
}
int findmin(int x)
{
int mid,l,r,w;
l=x-1,r=n+1;
while (r-l>1)
{
mid=(r+l)>>1;
w=query(x,mid,1,n,1);
if (w) r=mid;
else l=mid;
}
return r;
}
int findmax()
{
int mid,l,r,w;
l=0,r=n+1;
while (r-l>1)
{
mid=(r+l)>>1;
w=query(mid,n,1,n,1);
if (w) l=mid;
else r=mid;
}
return l;
}
int bsearch(int l,int r,int x,int len)
{
int mid,w,L=l+1;
while (r-l>1)
{
mid=(l+r)>>1;
w=query(L,mid,1,n,1);
if (w<len) l=mid;
else r=mid;
}
return r;
}
int main()
{
int T,i,m;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
memset(sum,0,sizeof(sum));
memset(col,-1,sizeof(col));
for (i=1;i<=n;i++) update(i,i,1,1,n,1);
while (m--)
{
int tp,x,y;
scanf("%d%d%d",&tp,&x,&y);
if (tp==1)
{
x++;
if (!y || !query(x,n,1,n,1))
{
printf("Can not put any one.\n");
continue;
}
int l=findmin(x);
int r=findmax();
if (query(l,r,1,n,1)>y) r=bsearch(l-1,r+1,x,y);
printf("%d %d\n",l-1,r-1);
update(l,r,0,1,n,1);

}else
{
x++,y++;
printf("%d\n",(y-x+1)-query(x,y,1,n,1));
update(x,y,1,1,n,1);
}
}
printf("\n");
}
return 0;
}



举报

相关推荐

0 条评论