HDU-4614 Vases and Flowers (线段树区间更新)
Posted 真正的强者,从不埋怨黎明前的黑暗!!!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-4614 Vases and Flowers (线段树区间更新)相关的知识,希望对你有一定的参考价值。
题目大意:有n个花瓶,每个花瓶中只能放一朵花。两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放;第二种是将区间[A,B]之间花瓶中的花清空。如果是第一种操作,输出这次放的花的左右端点;如果是第二种操作,输出这次总共清理出了多少支花。
题目分析:建立线段树,节点维护在相应的区间中,没有放入花的花瓶数目。有三种操作:一、查询某个区间中第k个没有插入花的花瓶位置;二、更新区间,使区间全部插入花;三、更新区间,使区间中的花瓶全部清空;
代码如下:
# include<iostream> # include<cstdio> # include<queue> # include<vector> # include<list> # include<map> # include<set> # include<cstdlib> # include<string> # include<cstring> # include<algorithm> using namespace std; # define LL long long const int N=50100; const int INF=1<<30; const double oo=1e20; const double eps=1e-20; int lazy[N*4+5]; int tr[N*4+5]; void pushDown(int rt,int l,int r) { if(lazy[rt]!=-1){ lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt]; if(lazy[rt]==1) tr[rt<<1]=tr[rt<<1|1]=0; else{ int mid=l+(r-l)/2; tr[rt<<1]=mid-l+1; tr[rt<<1|1]=r-mid; } lazy[rt]=-1; } } void pushUp(int rt) { tr[rt]=tr[rt<<1]+tr[rt<<1|1]; } void build(int rt,int l,int r) { tr[rt]=r-l+1; lazy[rt]=-1; if(l==r) return ; int mid=l+(r-l)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void update(int rt,int l,int r,int L,int R) { if(L<=l&&r<=R){ tr[rt]=0; lazy[rt]=1; }else{ pushDown(rt,l,r); int mid=l+(r-l)/2; if(L<=mid) update(rt<<1,l,mid,L,R); if(R>mid) update(rt<<1|1,mid+1,r,L,R); pushUp(rt); } } int clear(int rt,int l,int r,int L,int R) { if(L<=l&&r<=R){ int temp=tr[rt]; tr[rt]=r-l+1; lazy[rt]=0; return tr[rt]-temp; }else{ pushDown(rt,l,r); int mid=l+(r-l)/2; int res=0; if(L<=mid) res+=clear(rt<<1,l,mid,L,R); if(R>mid) res+=clear(rt<<1|1,mid+1,r,L,R); pushUp(rt); return res; } } int query(int rt,int l,int r,int L,int R) { if(L>r||R<l) return 0; ///这句话必须加上,否则query可能会一直被调用下去 if(L<=l&&r<=R) return tr[rt]; pushDown(rt,l,r); int mid=l+(r-l)/2; int res=0; if(L<=mid) res+=query(rt<<1,l,mid,L,R); if(R>mid) res+=query(rt<<1|1,mid+1,r,L,R); return res; } int ask(int rt,int l,int r,int L,int R,int num) { if(l==r){ return l; }else{ pushDown(rt,l,r); int mid=l+(r-l)/2; int t=query(rt<<1,l,mid,L,R); if(num<=t) return ask(rt<<1,l,mid,L,R,num); return ask(rt<<1|1,mid+1,r,L,R,num-t); } } int main() { int T,n,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); build(1,1,n); int k,a,b; while(m--) { scanf("%d%d%d",&k,&a,&b); if(k==1){ int t=query(1,0,n-1,a,n-1); if(t==0) printf("Can not put any one.\n"); else{ int l=ask(1,0,n-1,a,n-1,1); int r=ask(1,0,n-1,a,n-1,min(b,t)); printf("%d %d\n",l,r); update(1,0,n-1,l,r); } }else{ int ans=clear(1,0,n-1,a,min(n-1,b)); printf("%d\n",ans); } } printf("\n"); } return 0; }
以上是关于HDU-4614 Vases and Flowers (线段树区间更新)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 4614 Vases and Flowers 线段树+二分
HDU4614Vases and Flowers 二分+线段树;