hdu4031 Atack(树状数组区间更新单点求值)

来源:互联网 发布:钓鱼源码 编辑:程序博客网 时间:2024/06/05 17:44

题意说有一个长为n的防御墙,有n个防御装置,每个防御装置能放单位一的长度范围,且每次成功防御后需要d的时间恢复防御能力,在这之间受到攻击是不具备防御能力的。现在有个武器每秒钟能够发起一次攻击,范围是[a,b]。然后问某个点没能成功防住攻击的次数。

区间与点。。。。

显然求成功防御的次数较简单点,然后由总的被攻击次数减之。

首先需要纪录每秒攻击的范围,然后是点a从上一次攻击后回复防御能力的时间点rec[a]来表示。

/*****************************************Author      :Crazy_AC(JamesQi)Time        :2016File Name   :树状数组区间更新单点求值*****************************************/// #pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <algorithm>#include <iomanip>#include <sstream>#include <string>#include <stack>#include <queue>#include <deque>#include <vector>#include <map>#include <set>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <climits>using namespace std;#define MEM(x,y) memset(x, y,sizeof x)#define pk push_back#define lson rt << 1#define rson rt << 1 | 1#define bug cout << "BUG HERE\n"typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> ii;typedef pair<ii,int> iii;const double eps = 1e-10;const int inf = 1 << 30;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;int nCase = 0;const int maxn = 20010;typedef struct BIT {int sum[maxn];void init() {memset(sum, 0,sizeof sum);}int lowbit(int x) {return x & (-x);}void add(int x,int val) {while(x < maxn) {sum[x] += val;x += lowbit(x);}}int getsum(int x) {int ret = 0;while(x > 0) {ret += sum[x];x -= lowbit(x);}return ret;}}BIT;int l[maxn], r[maxn], cnt[maxn], rec[maxn];int n, q, d;int main(int argc, const char * argv[]){freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);int t;scanf("%d",&t);while(t--) {BIT solve;solve.init();memset(cnt, 0,sizeof cnt);memset(rec, 0,sizeof rec);int top = 0;scanf("%d%d%d",&n,&q,&d);printf("Case %d:\n", ++nCase);while(q--) {char op[10];int a, b;scanf("%s",op);if (op[0] == 'A') {scanf("%d%d",&a,&b);l[top] = a, r[top] = b;//纪录每秒钟攻击的范围top++;solve.add(a, 1), solve.add(b+1, -1);}else {scanf("%d",&a);for (int j = rec[a];j < top;++j) {//当前点成功防御的次数if (l[j] <= a && a <= r[j]) {cnt[a]++;rec[a] = j + d;//这次被攻击后恢复防御能力的时间点j += d - 1;}}//总攻击次数减去成功防御的次数printf("%d\n", solve.getsum(a) - cnt[a]);}}}return 0;}


0 0
原创粉丝点击