[HDU 4031]Attack[树状数组区间更新单点查询]

题目链接:[HDU 4031]Attack[树状数组区间更新单点查询]

题意分析:

『基地』组织又要打美国啦,如今他使用一种武器,可以攻打一个范围内的目标。但是米国有护盾,每个连续段内都有护盾,可以抵挡一次攻击。但是护盾有CD,

一次之后要过t时间才能回复,然而恐怖分子的没有CD,果然反派都是流弊XD。给出多个攻击和查询,每次查询输出该点被成功攻击了几次。

解题思路:

成功攻击次数怎么计算呢?很好的表示方法是:被攻击次数 - 成功抵御次数。那么问题来了,怎么计算抵御次数?可以另设一个数组pos记录当前查询时,x位置第一次抵御住攻击的次数。然后从这次开始往后查询到最新,如果有被攻击,那么就成功次数++并且更新一下成功抵御的位置。

而delta数组记录的是[x,n]这个区间的共同增量,所以segma(delta[i]) (0 < i <= x) 就是x这个点被攻击的次数。

个人感受:

终于是领略了三种模型了。点更+段查;段更+点查;段更+段查。这题理论上最坏情况能有1e8吧,不过不管啦,就酱紫XD。

具体代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#define lowbit(x) (x & (-x))
using namespace std;

const int MAXN = 2e4 + 111;

int n, q, t, delta[MAXN], pos[MAXN], defence[MAXN];
struct interval{
    int l, r;
}a[MAXN];

void add(int x, int val)
{
    while (x <= n)
    {
        delta[x] += val;
        x += lowbit(x);
    }
}

int getSum(int x)
{
    int ret = 0;
    while (x > 0)
    {
        ret += delta[x];
        x -= lowbit(x);
    }
    return ret;
}

int main()
{
    int up;
    char op[10];
    scanf("%d", &up);
    for (int kase = 1; kase <= up; ++kase)
    {
        printf("Case %d:\n", kase);
        scanf("%d%d%d", &n, &q, &t);
        memset(delta, 0, sizeof delta);
        memset(pos, 0, sizeof pos);
        memset(defence, 0, sizeof defence);
        int cnt = 0, l, r, x;
        while (q --)
        {
            scanf("%s", op);
            if (op[0] == 'A')
            {
                scanf("%d%d", &l, &r);
                a[cnt].l = l, a[cnt].r = r;
                ++cnt;
                add(l, 1);
                add(r + 1, -1);
            }
            else
            {
                scanf("%d", &x);
                for (int i = pos[x]; i < cnt; ++i)
                {
                    if (a[i].l <= x && x <= a[i].r)
                    {
                        pos[x] = i + t;
                        ++defence[x];
                        i += t - 1;
                    }
                }
                printf("%d\n", getSum(x) - defence[x]);
            }
        }
    }
    return 0;
}


你可能感兴趣的:(树状数组)