HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)
Attack
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 2523 Accepted Submission(s): 805
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.
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
题目链接: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(线段树/树状数组区间更新单点查询+暴力)的更多相关文章
- 【poj2155】Matrix(二维树状数组区间更新+单点查询)
Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...
- NBOJv2 1050 Just Go(线段树/树状数组区间更新单点查询)
Problem 1050: Just Go Time Limits: 3000 MS Memory Limits: 65536 KB 64-bit interger IO format: % ...
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...
- hdu1556 树状数组区间更新单点查询板子
就是裸的区间更新: 相对于直观的线段树的区间更新,树状数组的区间更新原理不太相同:由于数组中的一个结点控制的是一块区间,当遇到更新[l,r]时,先将所有能控制到 l 的结点给更新了,这样一来就是一下子 ...
- HDU 1556 Color the ball (树状数组 区间更新+单点查询)
题目链接 Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽&quo ...
- 【树状数组区间修改单点查询+分组】HDU 4267 A Simple Problem with Integers
http://acm.hdu.edu.cn/showproblem.php?pid=4267 [思路] 树状数组的区间修改:在区间[a, b]内更新+x就在a的位置+x. 然后在b+1的位置-x 树状 ...
- 【树状数组区间修改单点查询】HDU 4031 Attack
http://acm.hdu.edu.cn/showproblem.php?pid=4031 [题意] 有一个长为n的长城,进行q次操作,d为防护罩的冷却时间,Attack表示区间a-b的墙将在1秒后 ...
- hdu-3584 Cube---三维树状数组+区域更新单点查询
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3584 题目大意: 给定一个N*N*N多维数据集A,其元素是0或是1.A[i,j,k]表示集合中第 i ...
- POJ 2155 Matrix(二维树状数组+区间更新单点求和)
题意:给你一个n*n的全0矩阵,每次有两个操作: C x1 y1 x2 y2:将(x1,y1)到(x2,y2)的矩阵全部值求反 Q x y:求出(x,y)位置的值 树状数组标准是求单点更新区间求和,但 ...
随机推荐
- August 3rd, 2016, Week 32nd, Wednesday
I am looking for someone to share in an adventure. 我在找能和我一起分享冒险之旅的人. We are all looking for someone ...
- C++基础(1)
1.关于继承及访问. C++中 public,protected, private 访问标号小结,即访问标号使用限制. 第一:private, public, protected 访问标号的访问范围. ...
- Linux命令行下创建纳入版本控制下的新目录
[root@ok 资料库]# svn mkdir test A test [root@ok 资料库]# svn ci -m "mkdir test" Adding 资料库/test ...
- 数据库优化和SQL操作的相关题目
SQL操作 1.有一个数据库表peope,表有字段name,age,address三个属性(注:没有主键).现在如果表中有重复的数据,请删去重复只留下其中的一条.重复的定义就是两条记录的name,ag ...
- Pyqt在QListWidget中添加右键菜单
Pyqt 的资料奇少, 攻破难点之后, 就在这里记一下笔记. QListWidget 是继承 QWidget 的, 所以 QListWidget 是有右键菜单的, 从文档上可以找到 QWidget 上 ...
- javaWeb项目中web.xml的xsd( XML Schemas Definition)文件
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://w ...
- C++的那些事:流与IO类
1.流的概念 "流"就是"流动",是物质从一处向另一处流动的过程,比如我们能感知到的水流.C++的流是指信息从外部输入设备(如键盘和磁盘)向计算机内部(即内存) ...
- CodeForces Gym 100500A A. Poetry Challenge DFS
Problem A. Poetry Challenge Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...
- uva 10972(边双连通分量)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33804. 思路:和poj的一道题有点像,不过这道题图可能不连通,因 ...
- LoadRunner中多值关联的3种处理方式
需求:通过关联取得的ParamName参数可能存在多个值,需要对每个ParamName参数值进行处理 脚本:可通过3种不同的实现方式,将每个参数值作为HTTP请求内容发出 web_reg_save_ ...