HDU 1540 Tunnel Warfare(线段树)

题意:一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点。

分析:还是最大连续区间的板题,不过就是变成了单个节点进行更新。直接套用板子稍微更改就好,

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>

using namespace std;

const int maxn=5e4+10;

struct node{
    int ls,rs,ms;
}tree[maxn*4];
int n,m;

void build_tree(int l,int r,int i){
    tree[i].ls=tree[i].rs=tree[i].ms=r-l+1;
    if(l==r) return;
    int mid=l+r>>1;
    build_tree(l,mid,i<<1);
    build_tree(mid+1,r,i<<1|1);
}

bool all_space(int l,int r,int i){
    if(tree[i].ls==r-l+1) return 1;
    return 0;
}

int query(int t,int l,int r,int i){
    if(l==r||tree[i].ms==r-l+1||tree[i].ms==0){
        return tree[i].ms;
    }
    int mid=l+r>>1;
    if(t<=mid){
        if(t>=mid-tree[i<<1].rs+1){
            return query(t,l,mid,i<<1)+query(mid+1,mid+1,r,i<<1|1);
        }else return query(t,l,mid,i<<1);
    }else{
        if(t<=mid+tree[i<<1|1].ls){
            return query(t,mid+1,r,i<<1|1)+query(mid,l,mid,i<<1);
        }else return query(t,mid+1,r,i<<1|1);
    }
}

void change(int t,int l,int r,int i,int flag){
    if(l==r){
        if(!flag){         
            tree[i].ls=tree[i].rs=tree[i].ms=0;
        }else{
            tree[i].ls=tree[i].rs=tree[i].ms=1;
        }
        return;
    }
    int mid=l+r>>1;
    if(t<=mid) change(t,l,mid,i<<1,flag);
    else change(t,mid+1,r,i<<1|1,flag);
    tree[i].ls=tree[i<<1].ls;
    if(all_space(l,mid,i<<1))             
        tree[i].ls+=tree[i<<1|1].ls;

    tree[i].rs=tree[i<<1|1].rs;
    if(all_space(mid+1,r,i<<1|1))           
        tree[i].rs+=tree[i<<1].rs;
    tree[i].ms=max(tree[i<<1].rs+tree[i<<1|1].ls,max(tree[i<<1].ms,tree[i<<1|1].ms));
}

int main()
{
    while(~scanf("%d%d",&n,&m)){
        stack<int> st;
        memset(tree,0,sizeof tree);
        build_tree(1,n,1);
        while(m--){
            char ch;
            int a;
            scanf(" %c",&ch);
            if(ch=='D'){
                scanf("%d",&a);
                change(a,1,n,1,0);
                st.push(a);
            }else if(ch=='Q'){
                scanf("%d",&a);
                printf("%d\n",query(a,1,n,1));
            }else{
                if(st.empty()) continue;
                change(st.top(),1,n,1,1);
                st.pop();
            }
        }
    }
    return 0;
}

猜你喜欢

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