HDU5692 Snacks

Posted yspm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU5692 Snacks相关的知识,希望对你有一定的参考价值。

我太难了

(HDU) 卡前向星 , (POJ)(vector)

我真的是服了

Description

link

给定一棵树,要求支持如下操作:

(1.) 单点修改权值

(2.) 查询经过某点的权值和最大的链

Solution

其实挺简单的吧,就是先一遍 (dfs) 把树上的权值搞个前缀和

然后对 (dfn) 建线段树

单点改,区间查

屑题卡我半小时常,我现在也不知为啥链式前向星不对

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
		while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
		return res*f;
	}
	inline int max(int x,int y){return x>y?x:y;}
	const int N=1e5+10;
	int val[N];
	struct tree{
		int l,r,maxx,add;
		#define l(p) t[p].l
		#define r(p) t[p].r
		#define maxx(p) t[p].maxx
		#define add(p) t[p].add
	}t[N<<2];
	vector<int> g[N];
	inline void build(int p,int l,int r)
	{
		l(p)=l; r(p)=r; add(p)=0;
		if(l==r) return maxx(p)=val[l],void();
		int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r);
		maxx(p)=max(maxx(p<<1),maxx(p<<1|1));
		return ;
	}
	inline void spread(int p)
	{
		if(add(p))
		{
			maxx(p<<1)+=add(p); maxx(p<<1|1)+=add(p);
			add(p<<1)+=add(p); add(p<<1|1)+=add(p);
			add(p)=0;
		}return ;
	}
	inline void change(int p,int l,int r,int d)
	{
		if(l(p)>=l&&r(p)<=r)
		{
			add(p)+=d; maxx(p)+=d; 
			return ;
		} spread(p);
		int mid=(l(p)+r(p))>>1;
		if(l<=mid) change(p<<1,l,r,d); 
		if(r>mid) change(p<<1|1,l,r,d);
		maxx(p)=max(maxx(p<<1),maxx(p<<1|1));
		return ;
	}
	inline int ask(int p,int l,int r)
	{
		if(l<=l(p)&&r(p)<=r) return maxx(p);
		spread(p); int mid=(l(p)+r(p))>>1;
		int ans=-1e15-10;
		if(l<=mid) ans=max(ans,ask(p<<1,l,r));
		if(r>mid) ans=max(ans,ask(p<<1|1,l,r));
		maxx(p)=max(maxx(p<<1),maxx(p<<1|1));
		return ans; 
	}
	int tot,l[N],r[N],p[N],n,m;
	inline void dfs(int x,int fa)
	{
		l[x]=++tot; val[l[x]]=p[x]+val[l[fa]]; 
		int sz=g[x].size();
		for(int i=0;i<sz;++i) if(g[x][i]!=fa) dfs(g[x][i],x);
		r[x]=tot;
		return ;
	}
	int num;
	inline void work()
	{
		for(int i=1;i<=n;++i) g[i].clear();
		memset(t,0,sizeof(t)); memset(val,0,sizeof(val)); 
		memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); 
		++num; tot=0; 
		printf("Case #%lld:
",num);
		n=read(); m=read();
		for(int i=1;i<n;++i)
		{
			int u=1+read(),v=1+read();
			g[u].push_back(v); g[v].push_back(u);
		} 
		for(int i=1;i<=n;++i) p[i]=read();
		dfs(1,0); build(1,1,n);
		while(m--)
		{
			int opt=read();
			if(opt==1)
			{
				int x=read()+1; 
				printf("%lld
",ask(1,l[x],r[x]));
			}
			else 
			{
				int x=read()+1,y=read();
				change(1,l[x],r[x],y-p[x]);
				p[x]=y;
			}
		}
		return ;
	}
	signed main()
	{
		int T=read(); while(T--) work();
		return 0;
	}
}
signed main(){return yspm::main();}

以上是关于HDU5692 Snacks的主要内容,如果未能解决你的问题,请参考以下文章

HDU5692 Snacks

HDU5692 Snacks DFS+线段树

HDU 5692 - Snacks - [DFS序+线段树]

HDU5692 Snacks DFS序 线段树

hdu-5692 Snacks(dfs序+线段树)

hdu5692 Snacks dfs序+线段树