记录编号 374071 评测结果 AAAAAAAAAAA
题目名称 [河南省队2016]无根树 最终得分 100
用户昵称 Gravatar苦读依旧 是否通过 通过
代码语言 C++ 运行时间 1.161 s
提交时间 2017-02-22 11:14:20 内存使用 29.57 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
using namespace std;
struct E{
	int l,r;
	int lch,rch;
} t[520000];
struct Q{
	int l,r;
} tr[420000];
struct q{
int from;
int to;
int next;
} e[220000];
int tot=0;
int ma[420000];
int dep[120000];
int head[120000];
int fa[120000];
int size[120000];
int son[120000];
int a[120000];
int num[120000];
int top[120000];
int tid[120000];
int pos[120000];
bool vis[120000];
int lx[520000];
int mx[520000];
int rx[520000];
int sum[520000];
int c[120000];
int root[120000];
int bl[120000];
int rt=0;
int tt=0;
int k=0;
void insert(int x,int y)
{
	++tot; e[tot].from=x; e[tot].to=y;
	e[tot].next=head[x]; head[x]=tot;
}
void update(int now)
{
	int lch=t[now].lch; int rch=t[now].rch;
	sum[now]=sum[lch]+sum[rch];
	lx[now]=max(lx[lch],sum[lch]+lx[rch]);
	rx[now]=max(rx[rch],sum[rch]+rx[lch]);
	mx[now]=max(rx[lch]+lx[rch],max(mx[lch],mx[rch]));
}
void read(int &x)
{
	char c; bool flag=0;
	while((c=getchar())<'0'||c>'9') {
		if(c=='-') flag=1;
	}
	x=c-'0';
	while((c=getchar())<='9'&&c>='0') {
		x=(x<<1)+(x<<3)+c-'0';
	}
	if(flag) x=-x;
}
void dfs1(int x,int last)
{
	size[x]=1; int mxm=0;
	for(int i=head[x];i;i=e[i].next) {
		if(e[i].to!=last) {
			fa[e[i].to]=x;
			dep[e[i].to]=dep[x]+1;
			dfs1(e[i].to,x);
			size[x]+=size[e[i].to];
			if(size[e[i].to]>mxm) {
				mxm=size[e[i].to];
				son[x]=e[i].to;
			}
		}
	}
}
void dfs2(int x,int ancestor)
{
	vis[x]=1; top[x]=ancestor; num[ancestor]++; tid[++tt]=x; pos[x]=tt;
	if(!son[x]) return;
	dfs2(son[x],ancestor);
	for(int i=head[x];i;i=e[i].next) {
		if(e[i].to!=son[x]&&!vis[e[i].to]) {
			c[++rt]=e[i].to;
			dfs2(e[i].to,e[i].to);
		}
	}
}
void update1(int now)
{
	ma[now]=max(ma[now*2],ma[now*2+1]);
}
void build1(int now,int l,int r)
{
	tr[now].l=l; tr[now].r=r;
	int mid=(l+r)>>1;
	if(l==r) {
//		cout<<mx[root[l]]<<endl;
		ma[now]=mx[root[l]];
		return;
	}
	build1(now*2,l,mid); build1(now*2+1,mid+1,r);
	update1(now);
}
void update_point1(int now,int x,int v)
{
	int l=tr[now].l; int r=tr[now].r;
	int mid=(l+r)>>1;
	if(l==r) {
		ma[now]=v;
		return;
	}
	if(x<=mid) update_point1(now*2,x,v);
	else update_point1(now*2+1,x,v);
	update1(now);
}
int build(int tg,int l,int r)
{
	int now=++k; t[now].l=l; t[now].r=r;
	int mid=(l+r)>>1;
	if(l==r) {
//		cout<<l<<"    "<<a[tid[l]]<<endl;
		bl[l]=tg; lx[now]=a[tid[l]]; sum[now]=a[tid[l]]; 
		mx[now]=a[tid[l]]; rx[now]=a[tid[l]];
		return now;
	}
	t[now].lch=build(tg,l,mid); t[now].rch=build(tg,mid+1,r);
	update(now);
	return now;
}
void update_point(int now,int x,int v)
{
	int l=t[now].l; int r=t[now].r;
	int mid=(l+r)>>1;
	if(l==r) {
		lx[now]=v; sum[now]=v; mx[now]=v; rx[now]=v;
		return;
	}
	if(x<=mid) update_point(t[now].lch,x,v);
	else update_point(t[now].rch,x,v);
	update(now);
}
void addtion(int now,int x,int v)
{
	int l=t[now].l; int r=t[now].r;
	int mid=(l+r)>>1;
	if(l==r) {
		mx[now]+=v; lx[now]+=v; rx[now]+=v; sum[now]+=v;
		return;
	}
	if(x<=mid) addtion(t[now].lch,x,v);
	else addtion(t[now].rch,x,v);
	update(now);
}
/*void solve1(int x)
{
	int y=x;
	while(top[y]!=1) {
		y=top[y];
		if(lx[root[bl[pos[y]]]]>0) {
			addtion(root[bl[pos[fa[y]]]],pos[fa[y]],lx[root[bl[pos[y]]]]);
			update_point1(1,bl[pos[fa[y]]],mx[root[bl[pos[fa[y]]]]]);
		} else {
			break;
		}
		y=fa[y];
	}
}*/
void solve(int x,int last)
{
	int y=x; int cl;
	while(top[y]!=1) {
		y=top[y];
/*		if(lx[root[bl[pos[y]]]]>0) {
//			cout<<"              "<<lx[root[bl[pos[y]]]]<<endl;//
		//	update_point(root[bl[pos[fa[y]]]],pos[fa[y]],a[fa[y]]+lx[root[bl[pos[y]]]]);
			cl=lx[root[bl[pos[fa[y]]]]];
			addtion(root[bl[pos[fa[y]]]],pos[fa[y]],lx[root[bl[pos[y]]]]-max(last,0));
	//		cout<<root[bl[pos[fa[y]]]]<<"      "<<mx[root[bl[pos[fa[y]]]]]<<endl;
			update_point1(1,bl[pos[fa[y]]],mx[root[bl[pos[fa[y]]]]]);
			last=cl;
		} else {
			addtion(root[bl[pos[fa[y]]]],pos[fa[y]],0-max(last,0));
			update_point1(1,bl[pos[fa[y]]],mx[root[bl[pos[fa[y]]]]]);
			break;
		}*/
		cl=lx[root[bl[pos[fa[y]]]]];
		addtion(root[bl[pos[fa[y]]]],pos[fa[y]],max(0,lx[root[bl[pos[y]]]])-max(last,0));
		update_point1(1,bl[pos[fa[y]]],mx[root[bl[pos[fa[y]]]]]);
		last=cl;
		y=fa[y];
	}
}
int zz=0;
void Query(int now,int x)
{
	int l=t[now].l; int r=t[now].r;
	int mid=(l+r)>>1;
	if(l==r) {
		zz=now;
		return;
	}
	if(x<=mid) Query(t[now].lch,x);
	else Query(t[now].rch,x);
}
void dfs(int x,int fa)
{
	for(int i=head[x];i;i=e[i].next) {
		if(e[i].to!=fa) {
			dfs(e[i].to,x);
			if(bl[pos[e[i].to]]!=bl[pos[x]]&&c[bl[pos[e[i].to]]]==e[i].to) {
				addtion(root[bl[pos[x]]],pos[x],max(lx[root[bl[pos[e[i].to]]]],0));
				update_point1(1,bl[pos[x]],mx[root[bl[pos[x]]]]);
			}
		}
	}
}
int main()
{
	freopen("nortree.in","r",stdin);
	freopen("nortree.out","w",stdout);
	int n; read(n); int m; read(m);// scanf("%d",&n);
	for(int i=1;i<=n;++i) {
		int x; read(x); a[i]=x;
	}
	for(int i=1;i<=n-1;++i) {
		int x,y;// scanf("%d%d",&x,&y);
		read(x); read(y);
		insert(x,y); insert(y,x);
	}
	c[++rt]=1; dfs1(1,0); dfs2(1,1);
	for(int i=1;i<=rt;++i) {
		root[i]=build(i,pos[c[i]],pos[c[i]]+num[c[i]]-1);
	}
	build1(1,1,rt);
	dfs(1,0);
//	for(int i=rt;i>=1;--i) {
		//if(fa[c[i]]&&lx[root[i]]>0) {
			//update_point(root[bl[pos[fa[c[i]]]]],pos[fa[c[i]]],a[fa[c[i]]]+lx[root[i]]);
		//	solve(c[i],0);
		//}
//		if(fa[c[i]]&&lx[root[i]]>0) {
///			update_point(root[bl[pos[fa[c[i]]]]],pos[fa[c[i]]],a[fa[c[i]]]+lx[root[i]]);
//		}
//	}
//	for(int i=1;i<=rt;++i) {
//		printf("        %d\n",lx[root[i]]);
//	}
/*	int x,y; x=3; y=0;
	printf("%d   %d   %d\n",mx[root[bl[pos[x]]]],lx[root[bl[pos[x]]]],rx[root[bl[pos[x]]]]);
	update_point(root[bl[pos[x]]],pos[x],y);
	Query(root[bl[pos[x]]],pos[x]);
	cout<<mx[zz]<<"   "<<lx[zz]<<"   "<<rx[zz]<<endl;
	addtion(root[bl[pos[x]]],pos[x],y-a[x]);
	a[x]=y;
	printf("%d   %d   %d\n",mx[root[bl[pos[x]]]],lx[root[bl[pos[x]]]],rx[root[bl[pos[x]]]]);*/
	for(int i=1;i<=m;++i) {
		int opt; read(opt); 
		if(opt==1) {
			int x,y; read(x); read(y);
			int cl=lx[root[bl[pos[x]]]];
//			cout<<c<<endl;
			addtion(root[bl[pos[x]]],pos[x],y-a[x]);
//			cout<<mx[root[bl[pos[x]]]]<<endl;
//			cout<<son[1]<<endl;
//			cout<<top[x]<<endl;
//			cout<<bl[pos[x]]<<endl;
			update_point1(1,bl[pos[x]],mx[root[bl[pos[x]]]]);
			a[x]=y;
//			update_point(root[bl[pos[x]]],pos[x],y);
			solve(x,cl);
			continue;
		}
		if(opt==2) {
			printf("%d\n",max(0,ma[1]));
			continue;
		}
	}
	return 0;
}