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;
}                                   

 

posted on 2015-08-09 22:57  积跬步、至千里  阅读(130)  评论(0)    收藏  举报

导航