POJ4970Killing Monsters (用刷气球方法,非线段树)

Killing Monsters

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 179 Accepted Submission(s): 99

Problem Description

Kingdom Rush is a popular TD game, in which you should build some towers to protect your kingdom from monsters. And now another wave of monsters is coming and you need again to know whether you can get through it.

The path of monsters is a straight line, and there are N blocks on it (numbered from 1 to N continuously). Before enemies come, you have M towers built. Each tower has an attack range [L, R], meaning that it can attack all enemies in every block i, where L<=i<=R.
Once a monster steps into block i, every tower whose attack range include block i will attack the monster once and only once. For example, a tower with attack range [1, 3] will attack a monster three times if the monster is alive, one in block 1, another in
block 2 and the last in block 3.

A witch helps your enemies and makes every monster has its own place of appearance (the ith monster appears at block Xi). All monsters go straightly to block N.

Now that you know each monster has HP Hi and each tower has a value of attack Di, one attack will cause Di damage (decrease HP by Di). If the HP of a monster is decreased to 0 or below 0, it will die and disappear.

Your task is to calculate the number of monsters surviving from your towers so as to make a plan B.

Input

The input contains multiple test cases.

The first line of each case is an integer N (0 < N <= 100000), the number of blocks in the path. The second line is an integer M (0 < M <= 100000), the number of towers you have. The next M lines each contain three numbers, Li, Ri, Di (1 <= Li <= Ri <= N, 0
< Di <= 1000), indicating the attack range [L, R] and the value of attack D of the ith tower. The next line is an integer K (0 < K <= 100000), the number of coming monsters. The following K lines each contain two integers Hi and Xi (0 < Hi <= 10^18, 1 <= Xi
<= N) indicating the ith monster’s live point and the number of the block where the ith monster appears.

The input is terminated by N = 0.

Output

Output one line containing the number of surviving monsters.

Sample Input

5
2
1 3 1
5 5 2
5
1 3
3 1
5 2
7 3
9 1
0

Sample Output

3

Hint

In the sample, three monsters with origin HP 5, 7 and 9 will survive.

Source

2014 Multi-University Training Contest 9

PS:开始用线段树做超时,真心感觉刷气球方法不错。

#include<stdio.h>
#include<string.h>
#define MAXN 100005
__int64 sum[MAXN];
int main()
{
    __int64 s,n,m,L,R,k,i;
    while(scanf("%I64d",&n)>0&&n)
    {
        memset(sum,0,sizeof(sum));
        scanf("%I64d",&m);
        while(m--)
        {
            scanf("%I64d%I64d%I64d",&L,&R,&s);
            sum[L]+=s;sum[R+1]-=s;
        }
        s=0;
        for(i=1;i<=n;i++)
        {
            s+=sum[i];  sum[i]=s;//每个格子的数量
        }
        for(i=n-1;i>0;i--)
        sum[i]+=sum[i+1];
        scanf("%I64d",&k);
        m=0;
        while(k--)
        {
            scanf("%I64d%I64d",&s,&L);
            if(s>sum[L])m++;
        }
        printf("%I64d\n",m);
    }
}

POJ4970Killing Monsters (用刷气球方法,非线段树),布布扣,bubuko.com

时间: 2024-12-23 19:00:06

POJ4970Killing Monsters (用刷气球方法,非线段树)的相关文章

4970 Killing Monsters(前缀和问题)(类线段树)

Problem Description Kingdom Rush is a popular TD game, in which you should build some towers to protect your kingdom from monsters. And now another wave of monsters is coming and you need again to know whether you can get through it. The path of mons

非线段树 (前缀和解题)

N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色.但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗? Input每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N). 当N = 0,输入结束.Outp

ZKW线段树

对于区间问题,我们常用的方法是线段树.递归式的线段树具有通用性,但速度太慢.ZKW神犇使用非递归的线段树,常数特别小. 与大部分线段树一样,ZKW线段树采用堆式存储.也就是说,x节点的左儿子是x*2,右儿子是x*2+1,父亲是x/2. 由于采用非递归,我们要方便地找到叶子节点.ZKW线段树的方法是,从小到大枚举叶子节点数,直到线段树装得下.比如建立1000个节点,他从1开始枚举,2,4,8,16,--1024.发现1024足够大时,将[1, 1024)作为非叶节点,[1024, 2048)为叶子

BZOJ 3196 二逼平衡树 线段树+treap

题意:链接 方法:线段树+treap的模板题 题解: 首先是对于整个树的定义,其实treap部分并没有什么区别,只不过是单root改变为多root而已. #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define lson l,mid,rt<<1 #define rson mid+1,

hdu4288 Coder(线段树+离散化)

题目链接: huangjing 题意: 题目中给了三个操作 1:add x 就是把x插进去 2:delete x 就是把x删除 3:sum 就是求下标%5=3的元素的和. 还有一个条件是插入和删除最后都要保证数列有序... 首先告诉一种暴力的写法..因为时间非常充足,需要对stl里面的函数有所了解.. 就是直接申明一个vector的容器,然后直接用vector里面的操作比如 insert,erase等等操作..不过这个效率很低.. 最后跑出来6000多ms..(强哥的代码) 代码: #inclu

【BZOJ4094】[Usaco2013 Dec]Optimal Milking 线段树

[BZOJ4094][Usaco2013 Dec]Optimal Milking Description Farmer John最近购买了N(1 <= N <= 40000)台挤奶机,编号为1 ... N,并排成一行.第i台挤奶机每天能够挤M(i )单位的牛奶 (1 < =M(i) <=100,000).由于机器间距离太近,使得两台相邻的机器不能在同一天使用.Farmer Jo hn可以自由选择不同的机器集合在不同的日子进行挤奶.在D(1 < = D < = 50,00

P1243~P1247 线段树模板题总结

前言 这几天刚刚刷了5道线段树(水)题,现在来总结一下. 首先是犯的不少错误: 1.建树.更新函数没有return.这是最气的,每次最后程序错误查了半天也没查出来,最后发现是没有return.递归边界要return,递归边界要return,递归边界要return,重要的事情说三遍. 2.判断查找区间于线段的变量写反.听说这个是常犯错误. 然后说一下学线段树的收获.线段树的代码量的确多,很能练自己的思维,而且学的过程中简单的理解了一下#define的用处.线段树用来解决区间查询,区间修改都很方便,

线段树-进阶

上一次我们写的线段树已经可以解决区间查询.单点修改了!可喜可贺 那如果现在我们需要区间修改.区间查询呢? 一般有两种思路:lazytag和标记永久化,lazytag的使用面好像更广一些. 一.lazytag 比如我们现在要修改一个区间,我们可以像查询一样分成若干段,然后分别修改每一段. 那么问题来了,每一段要怎么修改?如果直接修改sum,询问就乱套了.如果暴力修改,最坏复杂度O(n),那还要线段树干嘛(╯‵□′)╯掀桌 那我们这么想,我们修改就不修改整个区间了,而是在区间上维护一个标记. 那我们

hdu 2795 Billboard(线段树单点更新)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 14337    Accepted Submission(s): 6148 Problem Description At the entrance to the university, there is a huge rectangular billboard of