HDU 1540 Tunnel Warfare

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


题意:有n个相邻的村子,D操作将该村子与左右的连接切断,R操作是将上次切断的道路恢复,Q操作是询问包括x在内的连续的村子


思路:线段树区间合并,和hotel不一样的是这题是单点更新,更新大同小异,因为是单点更新所以没用lazy标志,询问的时候比较不一样,判断改点是否在横跨左右子数的区间内,是则直接输出答案,否则继续向子树查询


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#define maxn 50030
using namespace std;

struct Tree
{
    int l,r;
    int lsum,rsum;
}tree[maxn*3];

stack <int> s;

void Pushup(int root)
{
    int ll=tree[root<<1].r-tree[root<<1].l+1;
    tree[root].lsum=tree[root<<1].lsum;
    if (tree[root].lsum==ll) tree[root].lsum+=tree[root<<1|1].lsum;
//cout<<":"<<root<<endl;
    int rr=tree[root<<1|1].r-tree[root<<1|1].l+1;
    tree[root].rsum=tree[root<<1|1].rsum;
    if (tree[root].rsum==rr) tree[root].rsum+=tree[root<<1].rsum;
}


void build(int root,int l,int r)
{
    tree[root].l=l;
    tree[root].r=r;
    tree[root].lsum=r-l+1;
    tree[root].rsum=r-l+1;
    if (l==r) return;
    int mid=(l+r)>>1;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
    Pushup(root);
}

void update(int root,int gold,int val)
{
//cout<<":"<<root<<endl;
    if (tree[root].l==tree[root].r)
    {
        if (val==0) tree[root].lsum=tree[root].rsum=0;
        else tree[root].lsum=tree[root].rsum=1;
        return;
    }

    int mid=(tree[root].l+tree[root].r)>>1;
    if (gold<=mid) update(root<<1,gold,val);
    else if (gold>mid) update(root<<1|1,gold,val);
    Pushup(root);
   // cout<<":"<<root<<endl;
}

int que(int root,int gold)
{

    if (tree[root].l==tree[root].r ) return tree[root].lsum;
    int mid=(tree[root].l+tree[root].r)>>1;
    int ll=mid-tree[root<<1].rsum+1;
    int rr=mid+tree[root<<1|1].lsum;//cout<<ll<<":"<<rr<<endl;
    if (gold>=ll && gold <=rr) return tree[root<<1].rsum+tree[root<<1|1].lsum;
    else if (gold<ll) return que(root<<1,gold);
    else if (gold>rr) return que(root<<1|1,gold);

}

int main()
{
    int n,m;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        //while (s.size()) s.pop();
        build(1,1,n);
        for (int i=0;i<m;i++)
        {
            char tem;
            cin>>tem;
            if (tem=='D')
            {
                int a;
                scanf("%d",&a);
                update(1,a,0);
                s.push(a);
            }
            else if (tem=='R')
            {
                int a=s.top();
                s.pop();
                update(1,a,1);
            }
            else if (tem=='Q')
            {
                int a;
                scanf("%d",&a);
                printf("%d\n",que(1,a));
            }
        }
    }
}



你可能感兴趣的:(数据结构,ACM)