[ACM] hrbustoj 1161 Leyni (树状数组)

2024-01-28 13:38

本文主要是介绍[ACM] hrbustoj 1161 Leyni (树状数组),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Leyni
Time Limit: 3000 MS Memory Limit: 65536 K
Total Submit: 247(56 users) Total Accepted: 78(53 users) Rating:  Special Judge: No
Description

Leyni被人掳走,身在水深火热之中...
小奈叶为了拯救Leyni,独自一人前往森林深处从静竹手中夺回昏迷中的Leyni。
历经千辛万苦,小奈叶救出了Leyni,但是静竹为此极为恼怒,决定对他们发起最强烈的进攻。
不过小奈叶有一个叫做能量保护圈的道具,可以保护他们。
这个保护圈由n个小的小护盾围成一圈,从1到n编号。当某一块小护盾受到攻击的时候,小护盾就会抵消掉这次攻击,也就是说对这一块小护盾的攻击是无效攻击,从而保护圈里的人,不过小护盾在遭到一次攻击后,需要t秒进行冷却,在冷却期间受到的攻击都是有效攻击,此时他们就会遭到攻击, 即假设1秒时受到攻击并成功防御,到1+t秒时冷却才结束并能进行防御,在2到t受到的都是有效攻击。

现在小奈叶专心战斗,Leyni昏迷,他们无法得知小护盾遭受的有效攻击次数,他们需要你的帮助。
只要能帮到他们,Leyni就会赠送出一份小奈叶写真集。
Input

第一行是一个整数T,表示有多少组测试数据。
第一行是三个整数,n,q,t,n表示保护圈的长度,q表示攻击的询问的总次数,t表示能量盾的冷却时间。
接下来的q行,每行表示受到的攻击或者她询问某范围内的能量盾被攻击的次数。
攻击:
Attack   a
表示编号为a的小护盾受到一次攻击, 保证 1 <= a <= n
询问:
Query  a  b
表示询问编号从a到b的小护盾(包括a和b)总共受到了多少次有效攻击。保证 1<=a,b<=n
第k次攻击发生在第k秒,询问不花费时间。
1 <= n,q <=100000
1 <= t <= 50。

Output

每一组测试数据,先输出一行"Case i:",i表示第i组测试数据,从1开始计数。
之后对于每一个询问,输出该范围内的小护盾受到的有效攻击次数,一个询问一行。

Sample Input

1
4 7 3
Attack 1
Attack 1
Attack 1
Attack 2
Attack 2
Query 1 4
Query 1 1

Sample Output

Case 1:
3
2

Author
黄李龙
解题思路:

 

编号1到n的保护盾,某编号的保护盾被攻击后产生防御,有个冷却时间t,如果在这t秒内该编号的盾又被攻击,则属于有效攻击,t秒后,该编号的盾又有了一次产生防御的能力。问某个区间内一共产生多少次有效攻击。用树状数组来保存区间有效攻击数,为每个盾保存一个状态,该状态为最后一次该盾产生防御是在第几次攻击d[number],当后来再对该盾产生攻击时,判断的d[number] + t 是否大于  该次攻击是第几次攻击,如果大于,则该次攻击属于有效攻击,更新树状数组,因为冷却时间还没完,否则,属于无效攻击,更新d[number]的值为  该次攻击是第几次攻击 。做题时犯了一个严重的错误,就是没有保存当前状态下一共发生了多少次攻击,直接把循环的变量当做攻击数了,但是题目中说查询是不需要时间的,所以要单独设一个变量来保存总发生攻击数。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn=100002;
int c[maxn];//保存数组中某一段区间的和
int d[maxn];//保存每个保护盾最后一次无效攻击发生在第几秒
int n,q,t;
char cm[10];//命令
int number;//被攻击的编号
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int rt)//这里rt为1
{
while(x<=n)
{
c[x]+=rt;
x+=lowbit(x);
}
}
int sum(int x)
{
int s=0;
while(x>0)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main()
{
int k;cin>>k;
for(int ti=1;ti<=k;ti++)
{
cout<<"Case "<<ti<<":"<<endl;
scanf("%d%d%d",&n,&q,&t);
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
int a,b;
int attacknum=0;
for(int i=1;i<=q;i++)
{
scanf("%s",cm);
if(cm[0]=='A')
{
attacknum++;
scanf("%d",&number);
if(d[number]==0)//第一次被攻击
{
d[number]=attacknum;
}
else
{
if(d[number]+t>attacknum)
update(number,1);
else//一开始犯了错误d[number]=i,这是错的,i既包括了攻击的时间也包括了查询时间,但题意中查询是不花时间的,所以不能用i
d[number]=attacknum;//编号为number的保护盾最后产生无效攻击发生在attacknum秒
}
}
if(cm[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%d\n",sum(b)-sum(a-1));//输出区间和
}
}
}
return 0;
}


 

这篇关于[ACM] hrbustoj 1161 Leyni (树状数组)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653783

相关文章

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

Java中数组转换为列表的两种实现方式(超简单)

《Java中数组转换为列表的两种实现方式(超简单)》本文介绍了在Java中将数组转换为列表的两种常见方法使用Arrays.asList和Java8的StreamAPI,Arrays.asList方法简... 目录1. 使用Java Collections框架(Arrays.asList)1.1 示例代码1.

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE