hdu 1540 Tunnel Warfare

题意:给你一个完整的1~n区间,他们是连续的,D代表破坏某个村庄,Q代表询问这个村庄何其他几何村庄相连,R代表修复村庄

思路:并不会用线段树维护区间,之前卡了好久,直到自己把样例画出来(还是太懒了),这才明白线段树维护区间的意思,,然后参照大牛的博客才水过

代码:

#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=50000+10;
int lsum[maxn<<2],rsum[maxn<<2];
int s[maxn],top,n,m,a;
char ch[2];
bool mark[maxn];

void pushdown(int i,int len)
{
    lsum[i]=lsum[i<<1];
    rsum[i]=rsum[i<<1|1];
    if(lsum[i]==len-(len>>1))lsum[i]+=lsum[i<<1|1];
    if(rsum[i]==(len>>1))rsum[i]+=rsum[i<<1];
}
void build(int l,int r,int i)
{
    lsum[i]=rsum[i]=r-l+1;
    if(l==r)return ;
    int mid=(l+r)>>1;
    build(l,mid,i<<1);
    build(mid+1,r,i<<1|1);
}
void update(int p,int date,int l,int r,int i)
{
    if(l==r){
        rsum[i]+=date;
        lsum[i]=rsum[i];
        return ;
    }
    int mid=(l+r)>>1;
    if(p<=mid)update(p,date,l,mid,i<<1);
    else update(p,date,mid+1,r,i<<1|1);
    pushdown(i,r-l+1);
}

int queryL(int L,int R,int l,int r,int i)
{
    if(L<=l&&r<=R){
        return lsum[i];
    }
    int mid=(l+r)>>1;
    if(R<=mid)queryL(L,R,l,mid,i<<1);
    else if(mid<L)queryL(L,R,mid+1,r,i<<1|1);
    else{
        int lans=queryL(L,mid,l,mid,i<<1);
        int rans=queryL(mid+1,R,mid+1,r,i<<1|1);
        if(lans==mid-L+1)return lans+rans;
        return lans;
    }
}
int queryR(int L,int R,int l,int r,int i)
{
    if(L<=l&&r<=R){
        return rsum[i];
    }
    int mid=(l+r)>>1;
    if(R<=mid)queryR(L,R,l,mid,i<<1);
    else if(mid<L)queryR(L,R,mid+1,r,i<<1|1);
    else{
        int lans=queryR(L,mid,l,mid,i<<1);
        int rans=queryR(mid+1,R,mid+1,r,i<<1|1);
        if(rans==R-mid)return lans+rans;
        return rans;
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m)){
        build(1,n,1);
        memset(mark,false,sizeof(mark));
        mark[0]=true,top=0;
        for(int i=0;i<m;i++){
            scanf("%s",ch);
            if(ch[0]=='D'){
                scanf("%d",&a);
                s[++top]=a;
                if(!mark[a])update(a,-1,1,n,1),mark[a]=true;
            }
            else if(ch[0]=='R'){
                while(!mark[s[top]])--top;
                if(top)update(s[top],1,1,n,1),mark[s[top--]]=false;
            }
            else{
                scanf("%d",&a);
                int temp=queryL(a,n,1,n,1)+queryR(1,a,1,n,1);
                printf("%d
",temp>0?temp-1:0);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lalalatianlalu/p/8467786.html