线段树是acm中的重要数据结构,故整理一个模板以便以后用。
//线段树模板 其中Max存区间的最大值
//操作1:插入一个值到一个区间
//操作2:询问一个区间的最大值
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define N 15000
//区间为[left , right]
struct node
{
int left,right;
int Max;
int addLevel; //记录线段树更新到此节点(此节点已经被更新)(表示其下的所有节点都需要更新,
//此处采用lazy更新),此是线段树精华所在
};
node tree[N * 4];
void buildTree(int n, int s,int e)
{
tree[n].left = s;
tree[n].right = e;
tree[n].Max = 0;
tree[n].addLevel = 0;
// 到达叶子节点
if(s == e)
{
return;
}
else
{
//递归建树
int mid = (s + e) >> 1;
//左子树[s,mid]
buildTree(n << 1,s,mid);
//右子树[mid + 1,e]
buildTree((n << 1) + 1,mid + 1,e);
}
//一般都需要回溯计算父亲节点值
}
//将[s,e]区间更新
void insert(int n,int s,int e,int d)
{
if(tree[n].left == s && tree[n].right == e)
{
tree[n].Max += d;
tree[n].addLevel += d;
return;
}
//进行lazy更新:更新其直接左右儿子节点,并更行左右儿子的addlevel值
if(tree[n].addLevel)
{
tree[n << 1].Max += tree[n].addLevel;
tree[n << 1].addLevel += tree[n].addLevel;
tree[(n << 1) + 1].Max += tree[n].addLevel;
tree[(n << 1) + 1].addLevel += tree[n].addLevel;
tree[n].addLevel = 0;
}
int mid = (tree[n].left + tree[n].right) >> 1;
if(mid >= e)
{
insert(n << 1,s,e,d);
}
else if(mid < s)
{
insert((n << 1) + 1,s,e,d);
}
else
{
insert(n << 1,s,mid,d);
insert((n << 1) + 1,mid + 1,e,d);
}
//一般都需要回溯计算父亲节点值
tree[n].Max = (tree[n << 1].Max > tree[(n << 1) + 1].Max ?
tree[n << 1].Max : tree[(n << 1) + 1].Max);
}
int search(int n,int s,int e)
{
if(tree[n].left == s && tree[n].right == e)
{
return(tree[n].Max);
}
//进行lazy更新:更新其直接左右儿子节点,并更行左右儿子的addlevel值
if(tree[n].addLevel)
{
tree[n << 1].Max += tree[n].addLevel;
tree[n << 1].addLevel += tree[n].addLevel;
tree[(n << 1) + 1].Max += tree[n].addLevel;
tree[(n << 1) + 1].addLevel += tree[n].addLevel;
tree[n].addLevel = 0;
}
int mid = (tree[n].left + tree[n].right) >> 1;
if(mid >= e)
{
return(search(n << 1,s,e));
}
else if(mid < s)
{
return(search((n << 1) + 1,s,e));
}
else
{
int l = search(n << 1,s,mid);
int r = search((n << 1) + 1,mid + 1,e);
return(l > r ? l : r);
}
}
int main()
{
int s,e,d,l;
int lMax,rMax,lLoc,rLoc,t;
while(scanf("%d",&l) != EOF)
{
memset(tree,0,sizeof(tree));
buildTree(1,0,l);
while(scanf("%d%d%d",&s,&e,&d))
{
if(s == -1) break;
insert(1,s,e,d);
}
lMax = rMax = lLoc = rLoc = 0;
for(int i = 0; i <= l ; ++i)
{
t = search(1,i,i);
if(lMax < t)
{
lMax = t;
lLoc = i;
}
if(rMax <= t)
{
rMax = t;
rLoc = i;
}
}
printf("%d %d\n",lLoc,rLoc);
}
return 0;
}