您的位置:首页 > 其它

HDU ACM 4031 Attack (树状数组--单点查询+区间更新)

2012-11-10 18:30 369 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4031

用了树状数组的区间更新 单点查找(一般为单点更新 区间查找)

例如 区间(2,4)加1

则Updata(2,1) Updata(4+1,-1)

实现了更新(2,4)的值而不改变其他值

求Sum时即可得到某一点的值

View Code

#include <iostream>
using namespace std;
const int MAX = 20000 + 100;
int C[MAX];
int N;
struct Node
{
int l;
int r;
};
int LowBit(int x)
{
return x & (-x);
}
void Update(int num,int key)
{
while(num <= N)
{
C[num] += key;
num += LowBit(num);
}
}

int CalSum(int num)
{
int sum = 0;
while(num > 0)
{
sum += C[num];
num -= LowBit(num);
}
return sum;
}
int main()
{
int T;
cin>>T;
int Case = 0;
while(T--)
{
int Q;//操作数量
int CD;//护盾冷却时间
int time = 0;//当前经过时间
int used_time[MAX] = {0};//记录护盾什么时候进入冷却
int porected[MAX] = {0};//记录保护次数
Node attack[MAX] = {0};//定义结构体,记录攻击的位置
memset(C,0,sizeof(C));
Case++;
cout<<"Case "<<Case<<":"<<endl;
scanf("%d%d%d",&N,&Q,&CD);
int i;
for(i=0;i<Q;i++)
{
char str[20];
scanf("%s",str);
if(str[0] == 'A')
{
scanf("%d%d",&attack[time].l,&attack[time].r);
Update(attack[time].l,1);
Update(attack[time].r+1,-1);
time++;
}
else
{
int num;
scanf("%d",&num);
int i;
for(i = used_time[num] ; i< time ;i++)//每一次询问计算被保护的次数
{
if(attack[i].l <=num    && num <= attack[i].r )
{
porected[num]++;
used_time[num] = i + CD;
i = i + CD - 1;
}
}
printf("%d\n",CalSum(num)-porected[num]);//成功攻击次数= 总攻击数 - 被保护次数
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: