码迷,mamicode.com
首页 > 其他好文 > 详细

HDU5692 Snacks

时间:2020-04-08 10:02:41      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:max   查询   build   lang   --   return   solution   poj   php   

我太难了

\(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:\n",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\n",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

标签:max   查询   build   lang   --   return   solution   poj   php   

原文地址:https://www.cnblogs.com/yspm/p/12657722.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!