首页 > 代码库 > HDU 4031 Attack(树状数组)

HDU 4031 Attack(树状数组)

Problem Description
Today is the 10th Annual of “September 11 attacks”, the Al Qaeda is about to attack American again. However, American is protected by a high wall this time, which can be treating as a segment with length N. Al Qaeda has a super weapon, every second it can attack a continuous range of the wall. American deployed N energy shield. Each one defends one unit length of the wall. However, after the shield defends one attack, it needs t seconds to cool down. If the shield defends an attack at kth second, it can’t defend any attack between (k+1)th second and (k+t-1)th second, inclusive. The shield will defend automatically when it is under attack if it is ready.

During the war, it is very important to understand the situation of both self and the enemy. So the commanders of American want to know how much time some part of the wall is successfully attacked. Successfully attacked means that the attack is not defended by the shield.
 

Input
The beginning of the data is an integer T (T ≤ 20), the number of test case.
The first line of each test case is three integers, N, Q, t, the length of the wall, the number of attacks and queries, and the time each shield needs to cool down.
The next Q lines each describe one attack or one query. It may be one of the following formats
1. Attack si ti
  Al Qaeda attack the wall from si to ti, inclusive. 1 ≤ si ≤ ti ≤ N
2. Query p
  How many times the pth unit have been successfully attacked. 1 ≤ p ≤ N
The kth attack happened at the kth second. Queries don’t take time.
1 ≤ N, Q ≤ 20000
1 ≤ t ≤ 50
 

Output
For the ith case, output one line “Case i: ” at first. Then for each query, output one line containing one integer, the number of time the pth unit was successfully attacked when asked.
 

Sample Input
2 3 7 2 Attack 1 2 Query 2 Attack 2 3 Query 2 Attack 1 3 Query 1 Query 3 9 7 3 Attack 5 5 Attack 4 6 Attack 3 7 Attack 2 8 Attack 1 9 Query 5 Query 3
 

Sample Output
Case 1: 0 1 0 1 Case 2: 3 2
 
题意:
美国建立了一套新的防御系统。每个点都可以进行自动防御,但是防御过后该点的防御
需要一段冷却时间,也就是说在此期间不能再进行防御。现在又两种操作:1.恐怖分子
每次会对一段范围进行攻击。2.指挥官询问某点被攻击的次数
BIT做法:我们知道由于询问不费时间,所以我们考虑设计一个数组tt[i]记录i点可以
进行防御的时间,当时间t>=tt[i]的时候表示攻击可以被防御。那么被攻击的次数=
总的攻击次数-防御次数。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
const int maxn = 20005;
int N,Q,T,t;
int c[maxn],d[maxn],tt[maxn];//tt[i]记录某点可以进行防御的时间,大于这个时间都可以进行防御;
struct  node//d[i]记录某点成功防御次数
{
    int l,r;
}e[maxn];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int w)
{
    while(x<maxn)
    {
        c[x]+=w;
        x+=lowbit(x);
    }
}
int query(int x)
{
    int s=0;
    while(x>0)
    {
        s+=c[x];
        x-=lowbit(x);
    }
    return s;
}
int main()
{
    int cas=1;
    int pos,l,r;
    char str[5];
    scanf("%d",&t);
    while(t--)
    {
        int cnt=0;
        CLEAR(c,0);
        CLEAR(tt,0);
        CLEAR(d,0);
        scanf("%d%d%d",&N,&Q,&T);
        printf("Case %d:\n",cas++);
        while(Q--)
        {
            scanf("%s",str);
            if(str[0]=='A')
            {
                scanf("%d%d",&l,&r);
                e[cnt].l=l;
                e[cnt++].r=r;
                update(l,1);
                update(r+1,-1);
            }
            else
            {
                scanf("%d",&pos);
                for(int i=tt[pos];i<cnt;i++)//记录某点可以进行防御的时间,大于等于该时间的攻击都可以自动进行防御
                {
                    if(pos>=e[i].l&&pos<=e[i].r)
                    {
                        d[pos]++;
                        tt[pos]=i+T;
                        i+=T-1;
                    }
                }
                printf("%d\n",query(pos)-d[pos]);
            }
        }
    }
    return 0;
}


HDU 4031 Attack(树状数组)