http://acm.hdu.edu.cn/showproblem.php?pid=4970
比赛的时候线段树水过的,比赛后线段树一直T,看了下正解真的是智商压制
题意:走直线,长度1-N,还有一些人,起点任意,每个人有血量,m个塔,每个塔有攻击范围和伤害,在一个点只会受到塔一次攻击,走到N存活,问存活个数
用一个数组ak记录塔的起点和终点情况,每个塔攻击起点加塔的伤害值,终点+1减伤害值
再用一个新数组sum,从前到后扫一遍可以知道每个点出发时的伤害(sum[i]=sum[i-1]+ak[i]),再从后往前扫一遍可以知道每个点到N的伤害(sum[i]+=sum[i+1])
这样得到的sum[i]就表示从i-N会损失的血量
#include <iostream> #include <cstdio> #include <cstring> using namespace std ; typedef __int64 ll ; ll ak[100005],sum[100005] ; int main() { int n ; while(~scanf("%d",&n),n) { int m,k ; scanf("%d",&m) ; memset(ak,0,sizeof(ak)) ; memset(sum,0,sizeof(sum)) ; while(m--) { int L,R,D ; scanf("%d%d%d",&L,&R,&D) ; ak[L]+=(ll)D ; ak[R+1]-=(ll)D ; } for(int i=1 ;i<=n ;i++) { sum[i]=sum[i-1]+ak[i] ; } for(int i=n-1 ;i>0 ;i--) { sum[i]+=sum[i+1] ; } scanf("%d",&k) ; int ans=0 ; while(k--) { int x ; ll h ; scanf("%I64d%d",&h,&x) ; if(sum[x]<h)ans++ ; } printf("%d\n",ans) ; } return 0 ; }