题意:
在一个[1,N]的直线上,有M个防御塔在某些位置上,对于一个灯塔,有其攻击范围[L,R]以及每次攻击的伤害值D,
有K个怪兽,每个怪兽有一个初始位置,随后会往N走,并且每个怪兽有一个血量H
而这个过程中防御塔会不断的攻击怪物,但对于一个怪兽,其在一个位置上只会受到若干灯塔的一次攻击(就是掉这个位置D的总和血)
现在问有多少个怪兽能活着走出N,也就是出了N其血量不为0。
题解:
区间更新,区间查询,就用线段树了.
更新就不用说了..查询就是查[Xi,N]的和是否大于Hi...
时间有点紧..用输入外挂..
Program:
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<queue>
#include<algorithm>
#define MAXN 100005
#define ll long long
#define oo 1000000007
using namespace std;
ll T[MAXN<<2],col[MAXN<<2];
int ReadInt()
{
int ans=0;
char c='?';
do
{
c=getchar();
}while (c<'0' || c>'9');
while (c>='0' && c<='9')
{
ans=ans*10+c-'0';
c=getchar();
}
return ans;
}
ll ReadInt64()
{
ll ans=0;
char c='?';
do
{
c=getchar();
}while (c<'0' || c>'9');
do
{
ans=ans*10+c-'0';
c=getchar();
}while (c>='0' && c<='9');
return ans;
}
void PushDown(int x,int L)
{
if (col[x])
{
col[x<<1]+=col[x];
col[x<<1|1]+=col[x];
T[x<<1]+=col[x]*((L+1)/2);
T[x<<1|1]+=col[x]*(L/2);
col[x]=0;
}
}
void Update(int l,int r,int L,int R,ll d,int x)
{
if (L<=l && R>=r)
{
T[x]+=d*(r-l+1);
col[x]+=d;
return;
}
PushDown(x,r-l+1);
int mid=l+r>>1;
if (L<=mid) Update(l,mid,L,R,d,x<<1);
if (R>mid) Update(mid+1,r,L,R,d,x<<1|1);
T[x]=T[x<<1]+T[x<<1|1];
return;
}
ll Query(int l,int r,int L,int R,int x)
{
if (L<=l && R>=r) return T[x];
PushDown(x,r-l+1);
int mid=l+r>>1;
ll ans=0;
if (L<=mid) ans+=Query(l,mid,L,R,x<<1);
if (R>mid) ans+=Query(mid+1,r,L,R,x<<1|1);
return ans;
}
int main()
{
int n,m,l,r,d,x,ans;
ll h;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
while (~scanf("%d",&n) && n)
{
scanf("%d",&m);
memset(T,0,sizeof(T));
memset(col,0,sizeof(col));
while (m--)
{
l=ReadInt(),r=ReadInt(),d=ReadInt();
Update(1,n,l,r,d,1);
}
scanf("%d",&m);
ans=0;
while (m--)
{
h=ReadInt64(),x=ReadInt();
if (h>Query(1,n,x,n,1)) ans++;
}
printf("%d\n",ans);
}
return 0;
}