Attack

Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 2523    Accepted Submission(s): 805

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
 

题目链接:HDU 4031

思路就是用线段树统计所有的攻击次数,再暴力统计防御次数,两者相减就是被攻击的次数,前面比较简单,后面怎么弄呢?建立数组pre[]代表上一次询问所防御到的位置,因此每一次统计的区间是上次询问时间到此次询问时间,这样可以达到不重复的统计,然后用数组d[]统计当前询问时的成功防御次数……

题目的时间轴应该是物理意义上的第k秒末而不是第k秒内,即某一秒是指一个瞬间而不是一个区间。因此实际冷却时间为t-1秒

就像这样:|____|____|____|____|      而不是    |____|____|____|____|

1    2     3     4     5           1     2     3     4

由于记录攻击的数组下标从0开始,因此每一次查询范围是 [pre[x],cnt)

线段树代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0); const int N=20010;
struct seg
{
int l,mid,r;
int sum,add;
};
seg T[N<<2];
int n,q,t; void pushup(int k)
{
T[k].sum=T[LC(k)].sum+T[RC(k)].sum;
}
void pushdown(int k)
{
if(T[k].add)
{
T[LC(k)].add+=T[k].add;
T[LC(k)].sum+=T[k].add*(T[LC(k)].r-T[LC(k)].l+1);
T[RC(k)].add+=T[k].add;
T[RC(k)].sum+=T[k].add*(T[RC(k)].r-T[RC(k)].l+1);
T[k].add=0;
}
}
void build(int k,int l,int r)
{
T[k].l=l;
T[k].r=r;
T[k].mid=MID(l,r);
T[k].add=T[k].sum=0;
if(l==r)
return ;
else
{
build(LC(k),l,T[k].mid);
build(RC(k),T[k].mid+1,r);
pushup(k);
} }
void update(int k,int l,int r,int val)
{
if(r<T[k].l||l>T[k].r)
return ;
if(l<=T[k].l&&r>=T[k].r)
{
T[k].add+=val;
T[k].sum+=val*(T[k].r-T[k].l+1);
}
else
{
pushdown(k);
update(LC(k),l,r,val);
update(RC(k),l,r,val);
pushup(k);
}
}
int query(int k,int x)
{
if(T[k].l==T[k].r&&T[k].l==x)
return T[k].sum;
pushdown(k);
if(x<=T[k].mid)
return query(LC(k),x);
else if(x>T[k].mid)
return query(RC(k),x);
}
pii range[N];
int pre[N];
int d[N];
int main(void)
{
int l,r,i,x,cur;
int tcase;
char ops[8];
scanf("%d",&tcase);
for (int c=1; c<=tcase; ++c)
{
int cnt=0;
CLR(pre,0);
CLR(d,0);
scanf("%d%d%d",&n,&q,&t);
build(1,1,n);
printf("Case %d:\n",c);
while (q--)
{
scanf("%s",ops);
if(ops[0]=='A')
{
scanf("%d%d",&l,&r);
update(1,l,r,1);
range[cnt++]=pii(l,r);
}
else
{
scanf("%d",&x);
int total=query(1,x);
for (cur=pre[x]; cur<cnt; )//范围就是上一次询问时间pre[x]到此次询问时间cnt
{
if(range[cur].first<=x&&x<=range[cur].second)
{
++d[x];
pre[x]=cur+t;//最近询问时间更新
cur+=t;//在此之后的t-1个都会防御失败,跳到第cur+t个
}
else
++cur;
}
printf("%d\n",total-d[x]);
}
}
}
return 0;
}

 

树状数组:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0); const int N=20010;
int T[N];
void add(int k,int val)
{
while (k<N)
{
T[k]+=val;
k+=(k&-k);
}
}
int getsum(int k)
{
int r=0;
while (k)
{
r+=T[k];
k-=(k&-k);
}
return r;
}
pii range[N];
int pre[N];
int d[N];
int n,q,t;
int main(void)
{
int l,r,i,x,cur;
int tcase;
char ops[8];
scanf("%d",&tcase);
for (int c=1; c<=tcase; ++c)
{
int cnt=0;
CLR(pre,0);
CLR(d,0);
CLR(T,0);
scanf("%d%d%d",&n,&q,&t);
printf("Case %d:\n",c);
while (q--)
{
scanf("%s",ops);
if(ops[0]=='A')
{
scanf("%d%d",&l,&r);
add(l,1);
add(r+1,-1);
range[cnt++]=pii(l,r);
}
else
{
scanf("%d",&x);
int total=getsum(x);
for (cur=pre[x]; cur<cnt; )//范围就是上一次询问时间pre[x]到此次询问时间cnt
{
if(range[cur].first<=x&&x<=range[cur].second)
{
++d[x];
pre[x]=cur+t;//询问时间更新
cur+=t;//在此之后的t-1个都会防御失败,跳到第cur+t个
}
else
++cur;
}
printf("%d\n",total-d[x]);
}
}
}
return 0;
}

HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)的更多相关文章

  1. 【poj2155】Matrix(二维树状数组区间更新+单点查询)

    Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...

  2. NBOJv2 1050 Just Go(线段树/树状数组区间更新单点查询)

    Problem 1050: Just Go Time Limits:  3000 MS   Memory Limits:  65536 KB 64-bit interger IO format:  % ...

  3. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  4. hdu1556 树状数组区间更新单点查询板子

    就是裸的区间更新: 相对于直观的线段树的区间更新,树状数组的区间更新原理不太相同:由于数组中的一个结点控制的是一块区间,当遇到更新[l,r]时,先将所有能控制到 l 的结点给更新了,这样一来就是一下子 ...

  5. HDU 1556 Color the ball (树状数组 区间更新+单点查询)

    题目链接 Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽&quo ...

  6. 【树状数组区间修改单点查询+分组】HDU 4267 A Simple Problem with Integers

    http://acm.hdu.edu.cn/showproblem.php?pid=4267 [思路] 树状数组的区间修改:在区间[a, b]内更新+x就在a的位置+x. 然后在b+1的位置-x 树状 ...

  7. 【树状数组区间修改单点查询】HDU 4031 Attack

    http://acm.hdu.edu.cn/showproblem.php?pid=4031 [题意] 有一个长为n的长城,进行q次操作,d为防护罩的冷却时间,Attack表示区间a-b的墙将在1秒后 ...

  8. hdu-3584 Cube---三维树状数组+区域更新单点查询

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3584 题目大意: 给定一个N*N*N多维数据集A,其元素是0或是1.A[i,j,k]表示集合中第 i ...

  9. POJ 2155 Matrix(二维树状数组+区间更新单点求和)

    题意:给你一个n*n的全0矩阵,每次有两个操作: C x1 y1 x2 y2:将(x1,y1)到(x2,y2)的矩阵全部值求反 Q x y:求出(x,y)位置的值 树状数组标准是求单点更新区间求和,但 ...

随机推荐

  1. 【pymongo】连接认证 auth failed解决方法

    故事背景: 我在虚拟机(ip:192.168.xx.xx)上建立了一个mongo的数据库,里面已经存好了内容.里面的一个database叫做 "adb", 里面有个collecti ...

  2. ACdream 1112 Alice and Bob(素筛+博弈SG函数)

    Alice and Bob Time Limit:3000MS     Memory Limit:128000KB     64bit IO Format:%lld & %llu Submit ...

  3. Light OJ 1199 - Partitioning Game (博弈sg函数)

    D - Partitioning Game Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  4. 在eclipse中打开项目所在的目录

    展开如下菜单: Run ---- External Tools ---- External Tools Configurations   在 program 下面新建一个工具 program--右击- ...

  5. Cocos2dx实现象棋之布局

    开始界面 #ifndef SCENESTART_H #define SCENESTART_H #include "cocos2d.h" #include "SceneGa ...

  6. select into from 提示 Undeclared variable.....错误的解决办法 && select into from 和 insert into select 的用法和区别

    然而今天在使用 SELECT INTO FROM 备份mysql数据表的时候,运行相关 sql 语句的时候却一直返回 [Err] 1327 - Undeclared variable: ...... ...

  7. Maven使用笔记(五)Sonatype Nexus 搭建Maven 私服

    1. 为什么使用Nexus 如果没有私服,我们所需的所有构件都需要通过maven的中央仓库和第三方的Maven仓库下载到本地, 而一个团队中的所有人都重复的从maven仓库下载构件无疑加大了仓库的负载 ...

  8. 如何为Linux生成和打上patch

    通过diff工具生成补丁, patch工具打上补丁. 在使用diff之前, 你需要保留一份未修改过的源码, 然后在其它地方修改源码的一份拷贝. diff对比这两份源码生成patch. 修改过的源码必须 ...

  9. Storm工程创建

    1.创建maven项目: pom.xml: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&quo ...

  10. Java Hour 17 来个CURD吧(二)

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 突然想到我最近一直在追的小说,作者每天都会更新两章,而且质量挺高.所以从这篇开 ...