HDU 4614-Vases and Flowers(线段树区间更新)
题意:
n个花瓶(0-n-1) 现有两个操作,
操作1 给a,f 从a位置开始向后连续插f个花(一个花瓶插一个)若当前花瓶有花则向后找,直到n-1位置如果还有多余的花则丢掉求查完花的第一和最后一个位置。
操作2 L,R 清空[l,r]花瓶内的花,并输出花的数量。
分析:
本题关键是用二分求插花的首末的位置,其他是基本的区间更新。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<1|1 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) #define N 50010 const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; int vempty[N*4],setv[N*4],n,q,p,pos; void pushup(int rt){ vempty[rt]=vempty[rt<<1]+vempty[rt<<1|1]; } void pushdown(int rt,int len){ if(setv[rt]!=-1){ setv[rt<<1]=setv[rt<<1|1]=setv[rt]; vempty[rt<<1]=(len-len/2)*setv[rt]; vempty[rt<<1|1]=len/2*setv[rt]; setv[rt]=-1; } } void build(int l,int r,int rt){ setv[rt]=-1; vempty[rt]=r-l+1; if(l==r)return ; int m=(l+r)>>1; build(lson); build(rson); } void update_add(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r){ vempty[rt]=setv[rt]=0; return; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m)update_add(L,R,lson); if(R>m)update_add(L,R,rson); pushup(rt); } void update_cle(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r){ setv[rt]=1; vempty[rt]=(r-l+1); return; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m)update_cle(L,R,lson); if(R>m)update_cle(L,R,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r){ return vempty[rt]; } pushdown(rt,r-l+1); int num=0; int m=(l+r)>>1; if(L<=m)num+=query(L,R,lson); if(R>m)num+=query(L,R,rson); pushup(rt); return num; } int main() { int t,k,a,b; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&q); build(1,n,1); while(q--){ scanf("%d%d%d",&k,&a,&b); if(k==1){ int ans=query(a+1,n,1,n,1); if(ans==0){ printf("Can not put any one.\n"); continue; } //二分首位置 int num=1,l=a+1,r=n,ll,rr; while(l<=r){ int m=(l+r)>>1; int tmp=query(a+1,m,1,n,1); if(tmp<num)l=m+1; else r=m-1; } ll=l; //二分末位置 num=ans<b?ans:b,l=a+1,r=n; while(l<=r){ int m=(l+r)>>1; int tmp=query(a+1,m,1,n,1); if(tmp<num)l=m+1; else r=m-1; } rr=l; printf("%d %d\n",ll-1,rr-1); update_add(ll,rr,1,n,1); } else{ int tmp=b-a+1-query(a+1,b+1,1,n,1); printf("%d\n",tmp); update_cle(a+1,b+1,1,n,1); } } printf("\n"); } return 0; }
浙公网安备 33010602011771号