HDU 4031 Attack 树状数组

题意:911事件十周年之际,美国建立了一套新的防御系统。每个点都可以进行自动防御,但是防御过后该点的防御需要一段冷却时间,也就是说在此期间不能再进行防御。现在又两种操作:1.恐怖分子每次会对一段范围进行攻击。2.指挥官询问某点成功防御的次数。
题解:参考http://blog.csdn.net/moorage/article/details/6785726

#include <iostream>
using namespace std;

#define N 20010
struct { int l, r; } attak[N]; /* 记录每一次攻击的范围 */

int def_time[N], def_num[N], attak_num[N]; /* def_time 记录某点可以进行防御的时间,大于等于该时间的攻击都可以自动进行防御 */
int L, Q, T;

int lowbit ( int x )
{
	return x & ( -x );
}

void update ( int pos, int v )
{
	for ( int i = pos; i <= L; i += lowbit(i) )
		attak_num[i] += v;
}

int getSum ( int pos ) /* 统计某一点总共受到的攻击次数 */
{
	int sum = 0;
	for ( int i = pos; i > 0; i -= lowbit(i) )
		sum += attak_num[i];
	return sum;
}

int main()
{
	char oper[10];
	int cs, l, r, pos;

	scanf("%d",&cs);
	for ( int i = 1; i <= cs; i++ )
	{
		int cnt = 0;
		printf("Case %d:\n",i);
		memset(def_time,0,sizeof(def_time));
		memset(def_num,0,sizeof(def_num));
		memset(attak_num,0,sizeof(attak_num));
		scanf("%d %d %d",&L,&Q,&T);

		while ( Q-- )
		{
			scanf("%s",oper);
			if ( oper[0] == 'A' )
			{
				cnt++;
				scanf("%d %d",&l, &r);
				attak[cnt].l = l;
				attak[cnt].r = r;
				update ( l, 1 );
				update ( r+1, -1 );
			}
			else
			{
				scanf("%d",&pos);
				for ( int i = def_time[pos]; i <= cnt; i++ )
				{
					if ( attak[i].l <= pos && pos <= attak[i].r )
					{
						def_num[pos]++;
					    def_time[pos] = i + T; /* 防御后,下一次可以防御的时间为 i + T */
					    i += T - 1;
					}
				}
				printf( "%d\n",getSum(pos) - def_num[pos] );
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值