HDU 5692 线段树
Posted Dan__ge
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5692 线段树相关的知识,希望对你有一定的参考价值。
题意:中文题目
思路:这还是第一次写这样的线段树,个人感觉是一种套路之前没做过,但是思想什么巧妙,将一颗树转化成线段树真厉害,先是将每个节点的下面的所有数进行dfs编序号,并将他们的左右编号记下来,也就是我的代码中的L和R,而val记录的是根节点0到当前位置的费用,建树之后就很好操作了,更新时便找到当前节点的儿子和自己代表的区间,然后区间更新,注意题目说更新一个节点的值变为y,我们为什么更新一段,因为我们线段树的节点保存的是到根节点0的费用,那么作为一个父亲节点,它的值变了,自然会影响它的所有儿子到根节点的费用,而且变化的相同,所以用区间更新来完成,查询也是一样,必须到x节点,那么到了x节点后是不是还会有更大的费用呢,而这个费用的点肯定要经过x节点,所以我们直接查询x节点和它的所有儿子的最大值即可 PS:树形的结构与线段树完美结合,要好好练练才行
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int maxn=100010;
vector<int>G[maxn];
ll max1[maxn*4],lazy[maxn*4],val[maxn];
int L[maxn],R[maxn],cost[maxn];
int idx;
void dfs(int u,int f,ll vv)
L[u]=++idx;
for(unsigned int i=0;i<G[u].size();i++)
int v=G[u][i];
if(v==f) continue;
dfs(v,u,(ll)cost[v]+vv);
R[u]=idx;
val[L[u]]=vv;
void pushup(int node)
max1[node]=max(max1[node<<1],max1[node<<1|1]);
void pushdown(int node)
if(lazy[node])
lazy[node<<1]+=lazy[node];
lazy[node<<1|1]+=lazy[node];
max1[node<<1]+=lazy[node];
max1[node<<1|1]+=lazy[node];
lazy[node]=0;
void buildtree(int le,int ri,int node)
if(le==ri)
max1[node]=val[le];
return ;
int t=(le+ri)>>1;
buildtree(le,t,node<<1);
buildtree(t+1,ri,node<<1|1);
pushup(node);
void update(int l,int r,int x,int le,int ri,int node)
if(l<=le&&ri<=r)
lazy[node]+=(ll)x;
max1[node]+=(ll)x;
return ;
pushdown(node);
int t=(le+ri)>>1;
if(l<=t) update(l,r,x,le,t,node<<1);
if(r>t) update(l,r,x,t+1,ri,node<<1|1);
pushup(node);
ll query(int l,int r,int le,int ri,int node)
if(l<=le&&ri<=r) return max1[node];
pushdown(node);
ll ans=-inf;
int t=(le+ri)>>1;
if(l<=t) ans=max(ans,query(l,r,le,t,node<<1));
if(r>t) ans=max(ans,query(l,r,t+1,ri,node<<1|1));
return ans;
int main()
int T,cas=1,n,m,a,b,c;
scanf("%d",&T);
while(T--)
scanf("%d%d",&n,&m);
for(int i=0;i<maxn;i++) G[i].clear();
for(int i=0;i<n-1;i++)
scanf("%d%d",&a,&b);
a++;b++;
G[a].push_back(b);
G[b].push_back(a);
for(int i=1;i<=n;i++) scanf("%d",&cost[i]);
idx=0;dfs(1,0,(ll)cost[1]);
buildtree(1,n,1);
memset(lazy,0,sizeof(lazy));
printf("Case #%d:\\n",cas++);
while(m--)
scanf("%d",&a);
if(a==0)
scanf("%d%d",&b,&c);b++;
update(L[b],R[b],c-cost[b],1,n,1);
cost[b]=c;
else
scanf("%d",&b);b++;
ll answe=query(L[b],R[b],1,n,1);
printf("%I64d\\n",answe);
return 0;
以上是关于HDU 5692 线段树的主要内容,如果未能解决你的问题,请参考以下文章