hdu5692 dfs序线段树
这是补的知识点,按先序遍历的顺序建立dfs序,用左右两个值代表整个区间,因为dfs序最重要的特点就是子树的区间是连续的
建立线段树时,需要用重新标过的 下标来建立
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<map> #include<set> #include<list> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define pil pair<int,ll> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=90000+10,inf=0x3f3f3f3f; struct edge{ int to,Next; }e[N*2]; int cnt,head[N]; void add(int u,int v) { e[cnt].to=v; e[cnt].Next=head[u]; head[u]=cnt++; } int l[N],r[N],id[N],num; ll a[N],d[N]; void dfs(int u,int f) { num++; l[u]=num; id[num]=u; for(int i=head[u]; ~i; i=e[i].Next) { int x=e[i].to; if(x==f)continue; d[x]=d[u]+a[x]; dfs(x,u); } r[u]=num; } ll lazy[N*4],sum[N*4]; void pushup(int rt) { sum[rt]=max(sum[rt<<1],sum[rt<<1|1]); } void pushdown(int rt) { if(lazy[rt]) { lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; sum[rt<<1]+=lazy[rt]; sum[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } } void build(int l,int r,int rt) { lazy[rt]=0; if(l==r) { sum[rt]=d[id[l]]; return ; } int m=(l+r)>>1; build(ls); build(rs); pushup(rt); } void update(int L,int R,int v,int l,int r,int rt) { if(L<=l&&r<=R) { sum[rt]+=v; lazy[rt]+=v; return ; } //if(l==r)return ; pushdown(rt); int m=(l+r)>>1; if(L<=m)update(L,R,v,ls); if(R>m)update(L,R,v,rs); pushup(rt); } ll query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R)return sum[rt]; //cout<<L<<" "<<l<<" "<<r<<" "<<R<<endl; // if(l==r)return -1e18; pushdown(rt); int m=(l+r)>>1; ll ans=-1e18; if(L<=m)ans=max(ans,query(L,R,ls)); if(R>m)ans=max(ans,query(L,R,rs)); return ans; } int main() { /* ios::sync_with_stdio(false); cin.tie(0);*/ int t,res=0; scanf("%d",&t); while(t--) { printf("Case #%d:\n",++res); int n,m; scanf("%d%d",&n,&m); cnt=0; memset(head,-1,sizeof head); for(int i=1; i<n; i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(int i=0; i<n; i++)scanf("%I64d",&a[i]); d[0]=a[0],num=0; dfs(0,-1); build(1,n,1); while(m--) { int op; scanf("%d",&op); if(op==0) { int x,y; scanf("%d%d",&x,&y); update(l[x],r[x],y-a[x],1,n,1); a[x]=y; } else { int x; scanf("%d",&x); // cout<<l[x]<<" "<<r[x]<<endl; printf("%I64d\n",query(l[x],r[x],1,n,1)); } // for(int i=0;i<n;i++)cout<<l[i]<<"*****"<<r[i]<<endl; } } return 0; } /******************** ********************/