HDU 4553 约会安排 (屌丝女神线段树)

分析:

可以看出来,女神的优先级比屌丝更高,那么屌丝占据的时间对女神来说这部分相当于没有没占据,而女神占据的时间对于屌丝来说还是被占据的。所以根据这点来看,就可以实现更改跟查询。

#include<bits/stdc++.h>

using namespace std;

const int maxn=1e5+10;

struct node{
    int mark;
    int dl,dr,dm;       //屌丝
    int nl,nr,nm;       //女神
}tree[maxn<<2];

void push_up(int l,int r,int i){
    int mid=l+r>>1;
    tree[i].dl=tree[i<<1].dl;
    tree[i].dr=tree[i<<1|1].dr;
    if(tree[i<<1].dl==mid-l+1) tree[i].dl+=tree[i<<1|1].dl;
    if(tree[i<<1|1].dr==r-mid) tree[i].dr+=tree[i<<1].dr;
    tree[i].dm=max(tree[i<<1].dr+tree[i<<1|1].dl,max(tree[i<<1].dm,tree[i<<1|1].dm));

    tree[i].nl=tree[i<<1].nl;
    tree[i].nr=tree[i<<1|1].nr;
    if(tree[i<<1].nl==mid-l+1) tree[i].nl+=tree[i<<1|1].nl;
    if(tree[i<<1|1].nr==r-mid) tree[i].nr+=tree[i<<1].nr;
    tree[i].nm=max(tree[i<<1].nr+tree[i<<1|1].nl,max(tree[i<<1].nm,tree[i<<1|1].nm));
}

void push_down(int l,int r,int i){
    if(tree[i].mark==0) return;
    int mid=l+r>>1;
    tree[i<<1].mark=tree[i<<1|1].mark=tree[i].mark;
    if(tree[i].mark==-1){
        tree[i<<1].dm=tree[i<<1].dl=tree[i<<1].dr=mid-l+1;
        tree[i<<1|1].dm=tree[i<<1|1].dl=tree[i<<1|1].dr=r-mid;
        tree[i<<1].nm=tree[i<<1].nl=tree[i<<1].nr=mid-l+1;
        tree[i<<1|1].nm=tree[i<<1|1].nl=tree[i<<1|1].nr=r-mid;
    }else{
        tree[i<<1].dl=tree[i<<1].dr=tree[i<<1].dm=0;
        tree[i<<1|1].dl=tree[i<<1|1].dr=tree[i<<1|1].dm=0;
        if(tree[i].mark==2){
            tree[i<<1].nl=tree[i<<1].nr=tree[i<<1].nm=0;
            tree[i<<1|1].nl=tree[i<<1|1].nr=tree[i<<1|1].nm=0;
        }else{
            tree[i<<1].nl=tree[i<<1].nr=tree[i<<1].nm=mid-l+1;
            tree[i<<1|1].nl=tree[i<<1|1].nr=tree[i<<1|1].nm=r-mid;
        }
    }
    tree[i].mark=0;
}

void build(int l,int r,int i){
    tree[i].mark=0;
    if(l==r){
        tree[i].dl=tree[i].dr=tree[i].dm=1;
        tree[i].nl=tree[i].nr=tree[i].nm=1;
        return;
    }
    int mid=l+r>>1;
    build(l,mid,i<<1);
    build(mid+1,r,i<<1|1);
    push_up(l,r,i);
}

void change(int tl,int tr,int l,int r,int i,int f){
    if(tl>r||tr<l) return;
    if(tl<=l&&r<=tr){
        if(f!=-1){
            tree[i].dl=tree[i].dr=tree[i].dm=0;
            if(f==2) tree[i].nl=tree[i].nr=tree[i].nm=0;
            else tree[i].nl=tree[i].nr=tree[i].nm=r-l+1;
        }else{
            tree[i].dl=tree[i].dr=tree[i].dm=r-l+1;
            tree[i].nl=tree[i].nr=tree[i].nm=r-l+1;
        }
        tree[i].mark=f;
        return;
    }
    push_down(l,r,i);
    int mid=l+r>>1;
    change(tl,tr,l,mid,i<<1,f);
    change(tl,tr,mid+1,r,i<<1|1,f);
    push_up(l,r,i);
}

int query_d(int len,int l,int r,int i){
    push_down(l,r,i);
    int mid=l+r>>1;
    if(tree[i<<1].dm>=len) return query_d(len,l,mid,i<<1);
    else if(tree[i<<1].dr+tree[i<<1|1].dl>=len) return mid-tree[i<<1].dr+1;
    else return query_d(len,mid+1,r,i<<1|1);
}

int query_n(int len,int l,int r,int i){
    push_down(l,r,i);
    int mid=l+r>>1;
    if(tree[i<<1].nm>=len) return query_n(len,l,mid,i<<1);
    else if(tree[i<<1].nr+tree[i<<1|1].nl>=len) return mid-tree[i<<1].nr+1;
    else return query_n(len,mid+1,r,i<<1|1);
}

int main(){
    int T;
    scanf("%d",&T);
    for(int cs=1;cs<=T;cs++){
        printf("Case %d:\n",cs);
        int n,m,a,b;
        scanf("%d%d",&n,&m);
        build(1,n,1);
        while(m--){
            char ch[10];
            scanf("%s",ch);
            if(ch[0]=='D'){
                scanf("%d",&a);
                if(tree[1].dm>=a){
                    int ans=query_d(a,1,n,1);
                    printf("%d,let's fly\n",ans);
                    change(ans,ans+a-1,1,n,1,1);
                }else printf("fly with yourself\n");
            }else if(ch[0]=='N'){
                scanf("%d",&a);
                if(tree[1].dm>=a){
                    int ans=query_d(a,1,n,1);
                    printf("%d,don't put my gezi\n",ans);
                    change(ans,ans+a-1,1,n,1,2);
                }else if(tree[1].nm>=a){
                    int ans=query_n(a,1,n,1);
                    printf("%d,don't put my gezi\n",ans);
                    change(ans,ans+a-1,1,n,1,2);
                }else printf("wait for me\n");
            }else{
                scanf("%d%d",&a,&b);
                change(a,b,1,n,1,-1);
                printf("I am the hope of chinese chengxuyuan!!\n");
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/83217406