HDU1540 Tunnel Warfare(单点修改&&区间合并)

题目大意

给定一个长度为n的全部为1的序列,可以对其进行以下三种操作:

1、D x 把第x个元素修改为0
2、Q x 查询包含第x个元素的全部为1的最长连续序列长度
3、R: 把最后一次修改的元素还原为1

题解

比较水的区间合并问题~~O(∩_∩)O~~。维护两个域即可,即包含节点左端的全部为1的最长连续序列长度lsum,包含节点右端的全部为1的最长连续序列长度rsum,对于某个查询,假设m为节点的中间位置,如果m-rsum[s<<1]+1<=x&&x<=m+lsum[s<<1|1](s为节点编号),则rsum[s<<1]+lsum[s<<1|1]就是查询的结果

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 50005
#define lson l,m,s<<1
#define rson m+1,r,s<<1|1
int lsum[MAXN<<2],rsum[MAXN<<2],a[MAXN];
void PushUp(int s,int m)
{
        lsum[s]=lsum[s<<1];
        rsum[s]=rsum[s<<1|1];
        if(lsum[s<<1]==(m-(m>>1))) lsum[s]+=lsum[s<<1|1];
        if(rsum[s<<1|1]==(m>>1)) rsum[s]+=rsum[s<<1];
}
void build(int l,int r,int s)
{
        lsum[s]=rsum[s]=r-l+1;
        if(l==r)
                return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
}
void update(int p,int d,int l,int r,int s)
{
        if(l==r) {
                lsum[s]=rsum[s]=d;
                return;
        }
        int m=(l+r)>>1;
        if(p<=m) update(p,d,lson);
        else
                update(p,d,rson);
        PushUp(s,r-l+1);
}
int query(int p,int l,int r,int s)
{
        if(l==r) return lsum[s];
        int m=(l+r)>>1;
        if(m-rsum[s<<1]+1<=p&&p<=m+lsum[s<<1|1]) return rsum[s<<1]+lsum[s<<1|1];
        if(p<=m) return query(p,lson);
        else
                return query(p,rson);
}
int main(void)
{
        int n,m,p,len;
        char op[5];
        while(scanf("%d%d",&n,&m)!=EOF) {
                len=0;
                build(1,n,1);
                while(m--) {
                        scanf("%s",op);
                        if(op[0]=='D') {
                                scanf("%d",&p);
                                update(p,0,1,n,1);
                                a[len++]=p;
                        } else if(op[0]=='R') {
                                update(a[len-1],1,1,n,1);
                                len--;
                        } else {
                                scanf("%d",&p);
                                printf("%d\n",query(p,1,n,1));
                        }
                }
        }
        return 0;
}
原文地址:https://www.cnblogs.com/zjbztianya/p/3114601.html