HDOJ 4031 - Attack 区间更新点查询的树状数组+暴力...

来源:互联网 发布:热动力学分析软件 编辑:程序博客网 时间:2024/06/13 15:56

               题意:

                       911十周年之际..恐怖份子准备再次发动攻击...现在设立了N个防御塔..每个防御塔抵挡了一次攻击后..要技能能却T时间后才能再次防御..而当一个防御塔处于冷却状态时,收到的攻击就会都接受...而恐怖份子的武器很厉害..每次会攻击一个连续的范围...现在告诉恐怖份子发动攻击的情况...并且中间询问某个防御塔成功受到了多少次攻击.

               题解:

                       把受到攻击的次数与成功防御的次数分开算...受到攻击的数目so easy了..区间更新点查询..一般使用线段树..这里学者用树状数组整..区间求和..比如要更新(l,r)每个数加1可以update(1,l),update(-1,r+1)..完成区间更新..而要查看某个位置x的值就直接看sum[x]...

                       统计成功防御次数..很暴力..记录一边做一边记录该点上一次成功防御的时刻...并且当询问该点时才更新...时间复杂度大致为O(M*N/T) 最坏情况


Program:

#include<iostream>#include<stdio.h>#include<string.h>#include<queue>#include<stack>#include<algorithm>#include<cmath>#include<set>#include<map>#include<time.h>#define ll long long#define oo 1<<29#define MAXN 50005#define pi acos(-1.0)#define esp 1e-30using namespace std;   int sum[MAXN],N;  void update(int x,int k){       while (k<=N)       {              sum[k]+=x;              k+=k&(-k);       }}int query(int k){       int ans=0;       while (k)       {              ans+=sum[k];              k-=k&(-k);       }       return ans;}char s[10];int pre[MAXN],attack[MAXN][2],d[MAXN];int main(){           int C,cases,M,T,i,x,l,r,An;         scanf("%d",&C);       for (cases=1;cases<=C;cases++)       {                scanf("%d%d%d",&N,&M,&T);                printf("Case %d:\n",cases);                memset(sum,0,sizeof(int)*(N+1));                memset(d,0,sizeof(int)*(N+1));                for (i=1;i<=N;i++) pre[i]=1;                An=0;                while (M--)                {                         scanf("%s",s);                         if (s[0]=='A')                          {                                 scanf("%d%d",&l,&r);                                 update(1,l),update(-1,r+1);                                 attack[++An][0]=l,attack[An][1]=r;                         }else                         {                                 scanf("%d",&x);                                 if (!T) { puts(0); continue; }                                 for (i=pre[x];i<=An;i++) //暴力更新防御次数                                    if (attack[i][0]<=x && attack[i][1]>=x)                                       d[x]++,pre[x]=i+T,i+=T-1;                                  printf("%d\n",query(x)-d[x]);                         }                }                       }       return 0;}


原创粉丝点击