HDU4553(线段树区间合并)

博客内容介绍了如何使用线段树处理区间合并的问题,特别强调了在更新屌丝区间时,若子区间标记为0(空闲状态),需要先进行子区间的更新,以确保女神区间状态正确。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题解:设两个区间表示屌丝剩下的区间,女神剩下的区间,然后用lazy思想更新一下,lazy = 0被更新成空闲的,lazy = 1表示这段区间被更新成屌丝的,lazy = 2表示这段区间被更新成女神的,lazy = -1表示这段区间不做任何操作。

注意一下更新屌丝的时候如果下面的是左右子区间lazy = 0时要先把左右子区间更新一下即可,这样才能确保左右子区间女神没有用

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define mid (L+R)/2
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,L,mid
#define rson rs,mid+1,R
const int mx = 1e5+5;
struct node{
    int lazy;
    int dl,dr,dm;
    int nl,nr,nm;
}T[mx<<2];
void built(int rt,int L,int R){
    T[rt].lazy = -1;
    T[rt].dl = T[rt].dr = T[rt].dm = R-L+1;
    T[rt].nl = T[rt].nm = T[rt].nr = R-L+1;
    if(L==R)
        return;
    built(lson);
    built(rson);
}
void push_up(int rt,int L,int R){
    if(mid-L+1==T[ls].dl)
        T[rt].dl = T[ls].dl+T[rs].dl;
    else
        T[rt].dl = T[ls].dl;
    if(R-mid==T[rs].dr)
        T[rt].dr = T[ls].dr+T[rs].dr;
    else
        T[rt].dr = T[rs].dr;
    T[rt].dm = max(T[ls].dr+T[rs].dl,max(T[ls].dm,T[rs].dm));
    if(mid-L+1==T[ls].nl)
        T[rt].nl = T[ls].nl+T[rs].nl;
    else
        T[rt].nl = T[ls].nl;
    if(R-mid==T[rs].nr)
        T[rt].nr = T[ls].nr+T[rs].nr;
    else
        T[rt].nr = T[rs].nr;
    T[rt].nm = max(T[ls].nr+T[rs].nl,max(T[ls].nm,T[rs].nm));
}
void push_down(int rt,int L,int R){
    if(L==R)
        return;
    if(T[rt].lazy!=-1){
        if(T[rt].lazy==0){
            T[ls].dl = T[ls].dm = T[ls].dr = T[ls].nl = T[ls].nm = T[ls].nr = mid-L+1;
            T[rs].dl = T[rs].dm = T[rs].dr = T[rs].nl = T[rs].nm = T[rs].nr = R-mid;
            T[ls].lazy = T[rs].lazy = 0;
            T[rt].lazy = -1;
        }
        else if(T[rt].lazy==1){
            if(T[ls].lazy==0)
                push_down(ls,L,mid);
            if(T[rs].lazy==0)
                push_down(rs,mid+1,R);
            T[ls].dl = T[ls].dm = T[ls].dr = 0;
            T[rs].dl = T[rs].dm = T[rs].dr = 0;
            T[ls].lazy = T[rs].lazy = 1;
            T[rt].lazy = -1;
        }
        else if(T[rt].lazy==2){
            T[ls].dl = T[ls].dm = T[ls].dr = 0;
            T[rs].dl = T[rs].dm = T[rs].dr = 0;
            T[ls].nl = T[ls].nm = T[ls].nr = 0;
            T[rs].nl = T[rs].nm = T[rs].nr = 0;
            T[ls].lazy = T[rs].lazy = 2;
            T[rt].lazy = -1;
        }
    }
}
int query_ns(int rt,int L,int R,int x){
    push_down(rt,L,R);
    if(L==R)
        return L;
    if(T[ls].nm>=x)
        return query_ns(lson,x);
    else if(T[ls].nr+T[rs].nl>=x)
        return mid-T[ls].nr+1;
    else
        return query_ns(rson,x);
}
int query_ds(int rt,int L,int R,int x){
    push_down(rt,L,R);
    if(L==R)
        return L;
    if(T[ls].dm>=x)
        return query_ds(lson,x);
    else if(T[ls].dr+T[rs].dl>=x)
        return mid-T[ls].dr+1;
    else
        return query_ds(rson,x);
}
void update(int rt,int L,int R,int l,int r,int v){
    push_down(rt,L,R);
    if(l <= L&&R <= r){
        if(v==0){
            T[rt].dl = T[rt].dm = T[rt].dr = T[rt].nl = T[rt].nm = T[rt].nr = R-L+1;
            T[rt].lazy = 0;
        }
        else if(v==1){
            T[rt].dl = T[rt].dm = T[rt].dr = 0;
            T[rt].lazy = 1;
        }
        else{
            T[rt].dl = T[rt].dm = T[rt].dr = T[rt].nl = T[rt].nm = T[rt].nr = 0;
            T[rt].lazy = 2;
        }
        return;
    }
    if(l>mid) update(rson,l,r,v);
    else if(r<=mid) update(lson,l,r,v);
    else{
        update(lson,l,mid,v);
        update(rson,mid+1,r,v);
    }
    push_up(rt,L,R);
}
int main(){
    int n,q,t,casei = 1;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&q);
        update(1,1,n,1,n,0);
        int ans;
        printf("Case %d:\n",casei++);
        while(q--){
            char s[20];
            int x,l,r;
            scanf("%s",s);
            if(s[0]=='D'){
                scanf("%d",&x);
                if(T[1].dm<x){
                    printf("fly with yourself\n");
                    continue;
                }
                ans = query_ds(1,1,n,x);
                printf("%d,let's fly\n",ans);
                update(1,1,n,ans,ans+x-1,1);
            }
            else if(s[0]=='N'){
                scanf("%d",&x);
                if(T[1].dm<x){
                    if(T[1].nm<x)
                        printf("wait for me\n");
                    else{
                        ans = query_ns(1,1,n,x);
                        update(1,1,n,ans,ans+x-1,2);
                        printf("%d,don't put my gezi\n",ans);
                    }
                }
                else{
                    ans = query_ds(1,1,n,x);
                    update(1,1,n,ans,ans+x-1,2);
                     printf("%d,don't put my gezi\n",ans);
                }
            }
            else{
                scanf("%d%d",&l,&r);
                update(1,1,n,l,r,0);
                printf("I am the hope of chinese chengxuyuan!!\n");
            }
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值