• 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;
    }
  • 相关阅读:
    HRBUST 1849 商品中心
    UVA 11600 Masud Rana
    Codeforces Round #580 (Div.1)
    loj 6270 数据结构板子题
    luogu P1758 [NOI2009]管道取珠
    luogu P1852 [国家集训队]跳跳棋
    51nod 2589 快速讨伐
    SICP_3.9-3.11
    SICP_3.7-3.8
    SICP_3.5-3.6
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3114601.html
Copyright © 2020-2023  润新知