Tunnel Warfare--- hdu1540 线段树求连续子区间

题目链接

题意:有n个村庄,编号分别为1-n;由于战争会破坏村庄,但是我们也会修复;

D x代表村庄x被破坏;

Q x是求与x相连的有几个没有被破坏;

R 是修复最后一次被破坏的村庄;

接下来有m个操作,对于每次Q操作输出结果;

由于修复的是最后一次被破坏的所以要用stack

 

接下来看代码吧,加个图好理解一点

 

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
using namespace std;

#define INF 0xfffffff
#define N 50050
#define Lson r<<1
#define Rson r<<1|1

struct SegmentTree
{
    int L, R, sum, lsum, rsum;

    int Mid() { return (L+R)>>1;}
    int len() { return R-L+1; }

} a[N<<2];

void Build(int r, int L, int R)
{
    a[r].L = L, a[r].R = R;
    a[r].sum = a[r].lsum = a[r].rsum = a[r].len();///刚开始的时候一定是区间所在长度;
    if(L == R) return;
    Build(Lson, L, a[r].Mid());
    Build(Rson, a[r].Mid()+1, R);
}

void Up(int r)///当下面的节点发生变化的时候我们要往上不断更新
{
    a[r].lsum = a[Lson].lsum;
    a[r].rsum = a[Rson].rsum;

    if(a[r].lsum == a[Lson].len())
        a[r].lsum += a[Rson].lsum;
    if(a[r].rsum == a[Rson].len())
        a[r].rsum += a[Lson].rsum;

    a[r].sum = max(max(a[Lson].lsum, a[Rson].rsum),a[Lson].rsum+a[Rson].lsum);
}

void Update(int r, int pos, int flag)///flag 为0表示破坏,1表示修复;
{///因为是直接更新到叶子节点的所以不需再往下更新,但是要往上更新;
    if(a[r].L == a[r].R && a[r].L==pos)
    {
        a[r].sum = a[r].lsum = a[r].rsum = flag;
        return ;
    }

    if(pos <= a[r].Mid())
        Update(Lson, pos, flag);
    else if(pos > a[r].Mid())
        Update(Rson, pos, flag);

    Up(r);
}

int Query(int r, int pos)
{
    if(a[r].sum == 0)return 0;

    if(pos < a[r].L + a[r].lsum) return a[r].lsum;///在最左边
    if(pos > a[r].R - a[r].rsum) return a[r].rsum;///在最右边

    if(pos > a[Lson].R - a[Lson].rsum && pos < a[Rson].L + a[Rson].lsum )///在中间部分;
        return a[Lson].rsum + a[Rson].lsum;

    if(pos <= a[r].Mid()) return Query(Lson, pos);///在左半边而非最左边;
    else return Query(Rson, pos);///在右半边而非最右边;
}

int main()
{
    int n, m, x;
    char s[110];
    while(scanf("%d %d", &n, &m)!=EOF)
    {
        Build(1, 1, n);
        stack<int> sta;
        for(int i=1; i<=m; i++)
        {
            scanf("%s", s);
            if(s[0] == 'D')
            {
                scanf("%d", &x);
                Update(1, x, 0);
                sta.push(x);///按破坏顺序一个一个的加入栈中
            }
            else if(s[0] == 'Q')
            {
                scanf("%d", &x);
                printf("%d\n", Query(1, x));
            }
            else
            {
                x = sta.top();
                sta.pop();
                Update(1, x, 1);
            }
        }
    }
    return 0;
}
View Code

 

posted @ 2015-08-01 11:46  西瓜不懂柠檬的酸  Views(207)  Comments(0Edit  收藏  举报
levels of contents