avatar
fireworks99
keep hungry keep foolish

HDU 1540 Tunnel Warfare(Segment Tree)

Description

N个点(1 ~ N),M个操作

D x 破坏点x

Q x 查询与x直接或间接相连的点(包括x自身)

R x 修复最近一次被破坏的点

Analyze

可以用 线段树 || 树状数组 || set

线段树:

a[num].lmax:包含区间左端点的最大连续子区间长度

a[num].rmax:包含区间右端点的最大连续子区间长度

a[num].ans:本区间最大连续子区间长度(仅用于剪枝:==0 return)

举例:

query(int num, int t)
int mid = (a[num].L + a[num].R) >> 1;
if(t <= mid)
{
    if(a[num << 1].rmax >= mid - t + 1)
    {
        ans += a[num << 1].rmax + a[num << 1 | 1].lmax;
        return ;
    }
    else
        query(num << 1, t);
}
else

Code

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 50005;

char s[10];
int n, m, des[N], last, ans;

struct node
{
    int L, R, ans, lmax, rmax;
}a[N << 2 | 1];

void up(int num)
{
    int mid = (a[num].L + a[num].R) >> 1;
    a[num].lmax = a[num << 1].lmax + (a[num << 1].lmax == mid - a[num].L + 1 ? a[num << 1 | 1].lmax : 0);
    a[num].rmax = a[num << 1 | 1].rmax + (a[num << 1 | 1].rmax == a[num].R - mid ? a[num << 1].rmax : 0);
    a[num].ans = max(max(a[num << 1].ans, a[num << 1 | 1].ans), a[num << 1].rmax + a[num << 1 | 1].lmax);
}

void init(int num, int l, int r)
{
    a[num].L = l;
    a[num].R = r;
    a[num].ans = a[num].lmax = a[num].rmax = 1;

    if(l == r)
        return ;

    int mid = (l + r) >> 1;
    init(num << 1, l, mid);
    init(num << 1 | 1, mid + 1, r);
    up(num);
}

void update(int num, int t, int val)
{
    if(a[num].L > t || a[num].R < t)
        return ;
    if(a[num].L == a[num].R && a[num].L == t)
    {
        a[num].ans = a[num].lmax = a[num].rmax = val;
        return ;
    }

    update(num << 1, t, val);
    update(num << 1 | 1, t, val);
    up(num);
}

void query(int num, int t)
{
    if(a[num].ans == 0 || a[num].L == a[num].R)
    {
        ans += a[num].ans;
        return ;
    }
    int mid = (a[num].L + a[num].R) >> 1;
    if(t <= mid)
    {
        if(a[num << 1].rmax >= mid - t + 1)
        {
            ans += a[num << 1].rmax + a[num << 1 | 1].lmax;
            return ;
        }
        else
            query(num << 1, t);
    }
    else
    {
        if(a[num << 1 | 1].lmax >= t - mid)
        {
            ans += a[num << 1].rmax + a[num << 1 | 1].lmax;
            return ;
        }
        else
            query(num << 1 | 1, t);
    }
}

int main()
{
    while(~scanf("%d %d", &n, &m))
    {
        init(1, 1, n);
        while(m--)
        {
            int t;
            scanf("%s", s);
            if(s[0] == 'D')
            {
                scanf("%d", &t);
                des[++last] = t;
                update(1, t, 0);
            }
            else if(s[0] == 'R')
                update(1, des[last--], 1);
            else
            {
                scanf("%d", &t);
                ans = 0, query(1, t);
                cout << ans << '\n';
            }
        }
    }
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy