题意:
在一个[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; }