#include<bits/stdc++.h> #define reg register int #define il inline #define fi first #define se second #define mk(a,b) make_pair(a,b) #define numb (ch^'0') using namespace std; typedef long long ll; template<class T>il void rd(T &x){ char ch;x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');} template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');} template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} #define mid ((l+r)>>1) namespace Miracle{ const int N=1e5+5; const int inf=0x3f3f3f3f; int n,m; struct node{ int nxt,to; }e[2*N]; int hd[N],cnt; void add(int x,int y){ e[++cnt].nxt=hd[x]; e[cnt].to=y; hd[x]=cnt; } int Max(int x,int y){ return x>y?x:y; } struct tr{ int a[2][2]; void init(){ memset(a,0,sizeof a); } tr friend operator *(const tr&a,const tr &b){ tr c;//c.init(); c.a[0][0]=Max(a.a[0][0]+b.a[0][0],a.a[0][1]+b.a[1][0]); c.a[0][1]=Max(a.a[0][0]+b.a[0][1],a.a[0][1]+b.a[1][1]); c.a[1][0]=Max(a.a[1][0]+b.a[0][0],a.a[1][1]+b.a[1][0]); c.a[1][1]=Max(a.a[1][0]+b.a[0][1],a.a[1][1]+b.a[1][1]); return c; } }S,A,B; struct seg{ int ls,rs; tr f; }t[4*N]; int tot; int rt[N]; void pushup(int x){ t[x].f=t[t[x].rs].f*t[t[x].ls].f; } void build(int &x,int l,int r){ x=++tot; if(l==r) { t[x].f.a[1][1]=-inf;return; } build(t[x].ls,l,mid); build(t[x].rs,mid+1,r); pushup(x); } void upda(int x,int l,int r,int p,int c1,int c2){//pos k add c if(l==r){ cout<<" upda "<<c1<<" "<<c2<<endl; //a[0][0],a[1][0] t[x].f.a[0][0]+=c1; t[x].f.a[1][0]+=c1; //a[0][1] t[x].f.a[0][1]+=c2; return; } if(p<=mid) upda(t[x].ls,l,mid,p,c1,c2); else upda(t[x].rs,mid+1,r,p,c1,c2); pushup(x); } tr query(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ cout<<t[x].f.a[0][0]<<" "<<t[x].f.a[0][1]<<" "<<t[x].f.a[1][0]<<" "<<t[x].f.a[1][1]<<endl; return t[x].f; } tr ret;ret.init(); if(mid<R) ret=ret*query(t[x].rs,mid+1,r,L,R); if(L<=mid) ret=ret*query(t[x].ls,l,mid,L,R); return ret; } int sz[N],son[N],dep[N],top[N],dfn[N],nd[N]; int df,fa[N]; void dfs1(int x,int d){ sz[x]=1; dep[x]=d; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(y==fa[x]) continue; fa[y]=x; dfs1(y,d+1); sz[x]+=sz[y]; if(sz[y]>sz[son[x]]) son[x]=y; } } int v[N]; int tmp[N]; void dfs2(int x){ dfn[x]=++df; if(!top[x]) top[x]=x; if(son[x]) top[son[x]]=top[x],dfs2(son[x]); for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(y==fa[x]||y==son[x]) continue; dfs2(y); } if(!son[x]) { build(rt[top[x]],dfn[top[x]],dfn[x]); nd[top[x]]=x; } } int f[N][2]; tr wrk(int x,int c){ cout<<" wrk "<<x<<" "<<c<<endl; // cout<<" wrk "<<x<<" "<<c<<endl; cout<<" rt "<<rt[top[x]]<<endl; upda(rt[top[x]],dfn[top[x]],dfn[nd[top[x]]],dfn[x],0,c-v[x]); while(1){ // cout<<" xx "<<x<<endl; const tr &tmp=S*query(rt[top[x]],dfn[top[x]],dfn[nd[top[x]]],dfn[top[x]],dfn[nd[top[x]]]); x=top[x]; if(fa[x]){ int y=fa[x]; upda(rt[top[y]],dfn[top[y]],dfn[nd[top[y]]],dfn[y],Max(tmp.a[0][0],tmp.a[0][1])-Max(f[x][0],f[x][1]),tmp.a[0][0]-f[x][0]); f[x][0]=tmp.a[0][0]; f[x][1]=tmp.a[0][1]; }else{ return tmp; } x=fa[x]; } } int main(){ rd(n);rd(m); for(reg i=1;i<=n;++i) rd(tmp[i]); int x,y; for(reg i=1;i<n;++i){ rd(x);rd(y); add(x,y);add(y,x); } dfs1(1,1); // cout<<" after dfs1 "<<endl; dfs2(1); prt(dfn,1,n); prt(son,1,n); prt(top,1,n); prt(nd,1,n); // cout<<" after dfs2 "<<endl; for(reg i=1;i<=n;++i){ A=wrk(i,tmp[i]); // cout<<" A "<<A.a[0][0]<<" "<<A.a[0][1]<<endl; } int c; while(m--){ rd(x);rd(c); A=wrk(x,c); v[x]=c; printf("%d\n",Max(A.a[0][0],A.a[0][1])); } return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2019/4/4 19:26:30 */View Code