记录编号 373764 评测结果 AAAAAAAAAAA
题目名称 [河南省队2016]无根树 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 3.975 s
提交时间 2017-02-21 19:05:27 内存使用 65.16 MiB
显示代码纯文本
#include<cstdio>
#include<queue>
using namespace std;
const int N=1e6+10;
int max(int x,int y){return x>y?x:y;}
struct edge{int f,t;}w[N];
int n,m,v[N],head[N],tail[N],next[N];
void add(int f,int t){
	static int cnt=0;
	w[++cnt]=(edge){f,t};
	if (!head[f]) head[f]=tail[f]=cnt;
		else tail[f]=next[tail[f]]=cnt;
}
int ans[4];
struct Segment_Tree{
	int v[N],best[N],bl[N],br[N],sum[N];
	#define lc x<<1
	#define rc x<<1|1
	void update(int x){
		sum[x]=sum[lc]+sum[rc];
		best[x]=max(br[lc]+bl[rc],max(best[lc],best[rc]));
		bl[x]=max(bl[lc],sum[lc]+bl[rc]);
		br[x]=max(br[rc],sum[rc]+br[lc]);
	}
	void change(int p,int d){
		int x=1,l=1,r=n;
		while (l<r){
			int mid=(l+r)>>1;
			if (p>mid) l=mid+1,x=rc;else r=mid,x=lc;
		}
		sum[x]+=d;v[l]+=d;
		best[x]=bl[x]=br[x]=max(v[l],0);
		for (x>>=1;x;x>>=1) update(x);
	}
	void getmax(int x,int l,int r,int L,int R,int *ans){
		if (l>=L&&r<=R){
			ans[0]=sum[x];
			ans[1]=bl[x];ans[2]=br[x];
			ans[3]=best[x];
			return;
		}
		int mid=(l+r)>>1,al[4]={0},ar[4]={0};
		if (R>mid) getmax(rc,mid+1,r,L,R,ar);
		if (L<=mid) getmax(lc,l,mid,L,R,al);
		ans[0]=al[0]+ar[0];
		ans[1]=max(al[1],al[0]+ar[1]);
		ans[2]=max(ar[2],ar[0]+al[2]);
		ans[3]=max(al[2]+ar[1],max(al[3],ar[3]));
	}
}T;
int fa[N],big[N],s[N],dfn[N],link[N],Right[N];
void dfs(int x){
	s[x]=1;
	for (int i=head[x];i;i=next[i])
	if (!fa[w[i].t]){
		fa[w[i].t]=x;
		dfs(w[i].t);
		s[x]+=s[w[i].t];
		if (s[big[x]]<s[w[i].t]) big[x]=w[i].t;
	}
}
void po(int x){
	static int cnt=0;
	dfn[x]=++cnt;
	link[x]=dfn[x]==dfn[fa[x]]+1?link[fa[x]]:x;
	Right[link[x]]=dfn[x];
	if (!big[x]) return;
	po(big[x]);
	for (int i=head[x];i;i=next[i])
	if (w[i].t!=fa[x]&&w[i].t!=big[x]) po(w[i].t);
}
struct heap{
	priority_queue<int> Q1,Q2;
	void push(int x){Q1.push(x);}
	void del(int x){Q2.push(x);}
	int top(){
		while (!Q2.empty()&&Q1.top()==Q2.top()) Q1.pop(),Q2.pop();
		return Q1.top();
	}
}H;
void cval(int p,int d){
	while (p){
		int top=link[p];
		T.getmax(1,1,n,dfn[top],Right[top],ans);
		int last=ans[1];
		H.del(ans[3]);
		T.change(dfn[p],d);
		T.getmax(1,1,n,dfn[top],Right[top],ans);
		p=fa[top];d=ans[1]-last;
		H.push(ans[3]);
	}
}
int main()
{
	freopen("nortree.in","r",stdin);
	freopen("nortree.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d",&v[i]);
	for (int i=1,f,t;i<n;i++){
		scanf("%d%d",&f,&t);
		add(f,t);add(t,f);
	}
	fa[1]=1;dfs(1);po(1);fa[1]=0;
	for (int i=1;i<=n;i++) H.push(0);
	for (int i=1;i<=n;i++) cval(i,v[i]);
	int tp,x,y;
	while (m--){
		scanf("%d",&tp);
		if (tp==1){
			scanf("%d%d",&x,&y);
			cval(x,y-v[x]);
			v[x]=y;
		}
		else printf("%d\n",H.top());
	}
	return 0;
}