zoj3573 Under Attack(区间更新 & 区间最值)
Doctor serves at a military air force base. One day, the enemy launch a sudden attack and the base is under heavy fire. The fighters in the airport must take off to intercept enemy bombers. However, the enemies know this clearly and they now focus on destroying the runway. The situation is becoming worse rapidly!
Every part of the runway has a damage level. On each bombing run, the damage level is increased by the bomb's damage . Fortunately, the enemy bombers has to stop bombing the runway when they run out of ammo. Then the ground crew have time to evaluate the situation of runway so that they can come to repair the runway ASAP after enemy attacks. The most heavily-damaged part on fighters' taking off and landing path should first be repaired. Assume that runway start from north and head to south , and fighters will take off or land only from north to south or vice versa.
Now that the task is clear, the ground crew need the cooridinates of two points: first that is the most damaged point from north to south, second is the most damaged point from south to north.The base's central mainframe is down under hacker attack. So Doctor could only use his poor little and shabby notebook to fulfill this task. Can you help him?
Input
The input consists of multiple cases.
The first line is the runway length L. L can be up to 15000.
Next lines will describe enemy bombing runs ,each line describes effect range start end of each bombing run and enemy bomb damage d.if start is -1, this case ends..
There can be up to 3000 bombing run, each time the damage is up to 100.
Notice that the bombing range is from north to south, and runway range is [0,len].
Output
Output the cooridinates of two points: first that is the most damaged point from north to south, second is the most damaged point from south to north.
Sample Input
10 1 5 2 6 9 2 -1 -1 -1
Sample Output
1 9
题目大意:这题的意思是给定区间[0,len];每次在区间[a,b]上伤害为c,求从左到右最大的伤害坐标,和从右到左的最大伤害坐标。
算法分析:一个线段树题目,每个区间都存储它伤害的程度,从左到右依次扫描每个元素,得到第一个坐标;从右到左依次扫描每个元素得到第二个元素;
View Code
#include<stdio.h>
#define N 15010
struct SegTree
{
int left;
int right;
int amount;
}tree[4*N];
int max,maxt,p1,p2;
void BuildSegTree(int root,int L,int R)
{
tree[root].left=L;
tree[root].right=R;
tree[root].amount=0;
if(L<R)
{
int M=(L+R)/2;
BuildSegTree(2*root,L,M);
BuildSegTree(2*root+1,M+1,R);
}
}
void AddSegTree(int root,int L,int R,int C)
{
if(L<=tree[root].left&&tree[root].right<=R)
{
tree[root].amount+=C;
return ;
}
int M=(tree[root].left+tree[root].right)/2;
if(R<=M) AddSegTree(2*root,L,R,C);
if(L>M) AddSegTree(2*root+1,L,R,C);
if(L<=M&&M<R)
{
AddSegTree(2*root,L,M,C);
AddSegTree(2*root+1,M+1,R,C);
}
}
void find_e(int root,int i)
{
if(tree[root].left<=i&&i<=tree[root].right)
maxt+=tree[root].amount;
if(tree[root].left==tree[root].right) return ;
int M=(tree[root].left+tree[root].right)/2;
if(i<=M) find_e(2*root,i);
if(i>M) find_e(2*root+1,i);
}
int main()
{
int n,i,a,b,c;
while(scanf("%d",&n)!=EOF)
{
BuildSegTree(1,1,n+1);
while(scanf("%d%d%d",&a,&b,&c)&&(a!=-1&&b!=-1&&c!=-1))
{
AddSegTree(1,a+1,b+1,c);
}
max=0;
for(i=1;i<=n+1;i++)
{
maxt=0;
find_e(1,i);
if(maxt>max)
{
max=maxt;p1=i;
}
}
max=0;
for(i=n+1;i>=1;i--)
{
maxt=0;
find_e(1,i);
if(maxt>max)
{
max=maxt;p2=i;
}
}
printf("%d %d\n",p1-1,p2-1);
}
return 0;
}


浙公网安备 33010602011771号