版权声明:Andy https://blog.csdn.net/Alibaba_lhl/article/details/81946933
Sample Input
24 4
0 8 1
8 12 10
12 20 8
20 24 5
4 3
0 3 1
1 2 2
2 4 5
10 10
8 9 15
1 7 5
5 10 3
0 7 6
5 8 2
3 7 3
2 9 12
7 8 14
6 7 2
5 6 16
Sample Output
132
13
108
Source::Click here
自己刚接触线段树,对线段树只是稍微理解了一点,先写了模板题。自己再悟悟吧,然后再写一个较为清晰的code.
#include<cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 5e4+10;
struct NODE
{
int l, r;
int value;//维护当前区间的(工作效率)最大值
}tree[MAXN<<2];
void build_tree(int rt, int l, int r)//建树
{
tree[rt].l = l;
tree[rt].r = r;
tree[rt].value = 0;
if(l+1==r) return ;//区间长度为1时,结束递归
int mid = (l+r)>>1;
build_tree(rt<<1,l,mid);//左儿子(注意左右儿子区间分别为[l, mid] 和 [mid, r])
build_tree(rt<<1|1,mid,r);//右儿子
}
void update(int rt, int l, int r, int v)//这个函数才用了贪心的思想
{
if(tree[rt].l>r || tree[rt].r<l) return ;//若该节点所在区间没有与[l,r]
if(tree[rt].l>=l && tree[rt].r<=r)//若该节点所在区间全包含在[l,r]内
{
tree[rt].value = max(tree[rt].value,v);
return ;
}
update(rt<<1,l,r,v);//继续向下更新左儿子
update(rt<<1|1,l,r,v);//继续向下更新右儿子
}
int query(int rt, int l, int r)
{
if(l+1==r) return tree[rt].value;
tree[rt<<1].value = max(tree[rt<<1].value,tree[rt].value);
tree[rt<<1|1].value = max(tree[rt<<1|1].value,tree[rt].value);
int mid = (l+r)>>1;
return query(rt<<1,l,mid) + query(rt<<1|1,mid,r);
}
int n, m;
int main()
{
while(~scanf("%d %d",&n,&m))
{
memset(tree,0,sizeof(tree));
build_tree(1,0,n);
while(m--)
{
int s, t, p;
scanf("%d %d %d",&s,&t,&p);
update(1,s,t,p);
}
printf("%d\n",query(1,0,n));
}
}
下面的代码的查询函数较容易理解一点吧!
#include<cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 5e4+3000;
struct NODE
{
int l, r;
int value;//维护当前区间的(工作效率)最大值
}tree[MAXN<<2];
void build_tree(int rt, int l, int r)//建树
{
tree[rt].l = l;
tree[rt].r = r;
tree[rt].value = 0;
if(l+1==r) return ;//区间长度为1时,结束递归
int mid = (l+r)>>1;
build_tree(rt<<1,l,mid);//左儿子(注意左右儿子区间分别为[l, mid] 和 [mid, r])
build_tree(rt<<1|1,mid,r);//右儿子
}
void update(int rt, int l, int r, int v)//这个函数才用了贪心的思想
{
if(tree[rt].l>r || tree[rt].r<l) return ;//若该节点所在区间没有与[l,r]
if(tree[rt].l>=l && tree[rt].r<=r)//若该节点所在区间全包含在[l,r]内
{
tree[rt].value = max(tree[rt].value,v);
return ;
}
update(rt<<1,l,r,v);//继续向下更新左儿子
update(rt<<1|1,l,r,v);//继续向下更新右儿子
}
ll sum;
void query(int rt, int l, int r)
{
if(l+1==r)
{
sum += tree[rt].value;
return ;
}
tree[rt<<1].value = max(tree[rt<<1].value,tree[rt].value);
tree[rt<<1|1].value = max(tree[rt<<1|1].value,tree[rt].value);
int mid = (l+r)>>1;
query(rt<<1,l,mid);
query(rt<<1|1,mid,r);
}
int n, m;
int main()
{
while(~scanf("%d %d",&n,&m))
{
memset(tree,0,sizeof(tree));
build_tree(1,0,n);
while(m--)
{
int s, t, p;
scanf("%d %d %d",&s,&t,&p);
update(1,s,t,p);
}
sum = 0;
query(1,0,n);
printf("%lld\n",sum);
}
}