Vases and Flowers HDU - 4614 (线段树 区间修改+二分查找)

1. 从a开始在空花瓶放b枝花,花放完或第N-1个花瓶放完为止 输出放花的第一个和最后一个位置

2. 将[a,b]的花都扔掉 输出扔了多少枝花

思路:

线段树维护[0,N-1]空花瓶数v

求a之前有多少空花瓶V(查[0,N-1]空花瓶数 - [a,N-1]空花瓶数)

二分查找放花的第一个和最后一个位置(

先求出可以放多少枝花,min ( [a,N-1]的空花瓶数 , b )

然后

二分查找第V+1个空瓶的位置 是第一个放花的位置

二分查找第V+b个空瓶的位置 是最后一个放花的位置)

因为维护的是区间空花瓶数的和 从[0,N-1]是递增的 仔细体会!

#include
using namespace std;
typedef long long ll;
#define lson (pos<<1)
#define rson (pos<<1|1)
const int maxn=55555;
struct Node{
    int l,r;
    int v,col;//v 空花瓶数, col lazy标记
}node[maxn<<2];
int N,M;
void pushup(int pos){
    node[pos].v=node[lson].v+node[rson].v;
}
void pushdown(int pos){
    if(node[pos].col>=0){//有被标记
        node[lson].col=node[pos].col; node[rson].col=node[pos].col;
        node[lson].v=(node[lson].r-node[lson].l+1)*node[pos].col;
        node[rson].v=(node[rson].r-node[rson].l+1)*node[pos].col;
        node[pos].col=-1;
    }
}
void Build(int L,int R,int pos){
    node[pos].l=L; node[pos].r=R; node[pos].col=-1;//初始化
    if(L==R){ node[pos].v=1; return;}//叶子 递归边界 
    int m=(L+R)>>1;
    Build(L,m,lson); Build(m+1,R,rson); pushup(pos);//回溯前由现在的节点更新父节点
}
void UpDate(int L,int R,int pos,int value){
    if(L <= node[pos].l && node[pos].r <= R){
        node[pos].v = (node[pos].r - node[pos].l + 1) * value;
        node[pos].col = value;
        return;
    }
    pushdown(pos);
    int m = (node[pos].l + node[pos].r) >> 1;
    if(L<=m) UpDate(L,R,lson,value);
    if(R>m) UpDate(L,R,rson,value);
    pushup(pos);
}
int Query_sum(int L,int R,int pos){//空花瓶数
    if(L<=node[pos].l&&node[pos].r<=R) return node[pos].v;
    pushdown(pos);//递归前下推标记
    int m=(node[pos].l+node[pos].r)>>1;
    int ret=0;
    if(L<=m) ret+=Query_sum(L,R,lson); //都是L、R
    if(R>m) ret+=Query_sum(L,R,rson);
    pushup(pos);
    return ret;
}
void Search(int value,int pos,int &p){
    if(node[pos].l==node[pos].r){ p=node[pos].l; return; }
    pushdown(pos);
    int m=(node[pos].l+node[pos].r)>>1;
    if(node[lson].v>=value) Search(value,lson,p);
    else Search(value-node[lson].v,rson,p);
    pushup(pos);
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        Build(0,N-1,1);
        int op,a,b;
        for(int i=0;i

 

你可能感兴趣的:(数据结构-线段树)