hdu 1540 Tunnel Warfare (单点更新,区间合并)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1540

题意:

开始都为,D为破坏一个村子,R为修复最后一个被破坏的村子,Q为查询包括该点的最长连续区间。

#include
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
const int maxn=1e5+10;

int n,m;
struct node{
    int l,r;
    int lsum;  //从该点向左,共有lsum个连续区间
    int rsum;  //从该点向右,共有rsum个连续区间
    int sum;   //该点连续区间长度
}t[maxn<<2];
int lazy[maxn<<2];
stack  s;

void up(int rt,int l,int r){
    t[rt].lsum=t[rt<<1].lsum;
    t[rt].rsum=t[rt<<1|1].rsum;
    int mid=(l+r)>>1;
    if(t[rt].lsum==mid-l+1) t[rt].lsum+=t[rt<<1|1].lsum;
    if(t[rt].rsum==r-mid ) t[rt].rsum+=t[rt<<1].rsum;
    t[rt].sum=max(t[rt<<1].rsum+t[rt<<1|1].lsum,max(t[rt<<1].sum,t[rt<<1|1].sum));
}

void build(int rt,int l,int r){
    t[rt].l=l,t[rt].r=r;
    t[rt].sum=t[rt].lsum=t[rt].rsum=r-l+1;
    if(l==r)  return ;
    int mid=(l+r)>>1;
    build(lson),build(rson);
}

void update(int rt,int x,int k){ //1是破坏
    if(t[rt].l==t[rt].r){
        t[rt].sum=t[rt].lsum=t[rt].rsum=k;
        return ;
    }
    int mid=(t[rt].l+t[rt].r)>>1;
    if(x<=mid) update(rt<<1,x,k);
    else update(rt<<1|1,x,k);
    up(rt,t[rt].l,t[rt].r);
}

int query(int rt,int x){
    if(t[rt].l==t[rt].r || t[rt].sum==0 || t[rt].sum==t[rt].r-t[rt].l+1)//叶子节点或者该访问区间为空或者已满
        return t[rt].sum;
    int mid=(t[rt].l+t[rt].r)>>1;
    if(x<=mid){
        if(x>=t[rt<<1].r-t[rt<<1].rsum+1)
            return query(rt<<1,x)+query(rt<<1|1,mid+1);
        else
            return query(rt<<1,x);
    }
    else{
        if(x<=t[rt<<1|1].l+t[rt<<1|1].lsum-1)
            return query(rt<<1|1,x)+query(rt<<1,mid);
        else
            return query(rt<<1|1,x);
    }
}

int main(){
    while(cin>>n>>m){
        build(1,1,n);
        while(m--){
            char ch;
            int x;
            cin>>ch;
            if(ch=='D'){
                cin>>x, s.push(x);
                update(1,x,0);
            }
            else if(ch=='Q'){
                cin>>x;
                int ans=query(1,x);
                printf("%d\n",ans);
            }
            else{
                x=s.top(), s.pop();
                update(1,x,1);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(线段树)