题解:神奇的动态dp,orz
模板:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100001;
int a[N],e[N*2],head[N],next[N*2],cnt,tot,n,q[N],fa[N],sz[N],son[N],top[N],ed[N],pos[N],idx[N];
ll f[N][2];
struct matrix{
ll g[2][2];
matrix(){memset(g,0,sizeof(g));}
matrix operator *(const matrix &b)const{
matrix c;
int i,j,k;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<2;k++)c.g[i][j]=max(c.g[i][j],g[i][k]+b.g[k][j]);
return c;
}
}val[N],d[N*4];
void build(int t,int k){
tot++;
e[tot]=k;
next[tot]=head[t];head[t]=tot;
}
void init(){
q[1]=1;
int u,i,j,l=0,r=1;
while(l<r){
u=q[++l];
for(i=head[u];i;i=next[i])
if(e[i]!=fa[u]){
fa[e[i]]=u;q[++r]=e[i];
}
}
for(i=n;i;i--){
sz[q[i]]++;
sz[fa[q[i]]]+=sz[q[i]];
if(sz[q[i]]>sz[son[fa[q[i]]]])son[fa[q[i]]]=q[i];
}
for(i=1;i<=n;i++)
if(!top[q[i]]){
for(j=q[i];j;j=son[j])top[j]=q[i],idx[pos[j]=++cnt]=j;
ed[q[i]]=cnt;
}
for(i=n;i;i--){
u=q[i];
f[u][1]=max(0,a[u]);
for(j=head[u];j;j=next[j])
if(e[j]!=fa[u]){
f[u][0]+=max(f[e[j]][0],f[e[j]][1]);
f[u][1]+=f[e[j]][0];
}
}
}
void bt(int x,int l,int r){
int u,i;
if(l==r){
ll g0=0,g1=a[idx[l]];
u=idx[l];
for(i=head[u];i;i=next[i])
if(e[i]!=fa[u]&&e[i]!=son[u])g0+=max(f[e[i]][0],f[e[i]][1]),g1+=f[e[i]][0];
d[x].g[0][0]=d[x].g[0][1]=g0;
d[x].g[1][0]=g1;
val[l]=d[x];
return;
}
int mid=(l+r)/2;
bt(x*2,l,mid);bt(x*2+1,mid+1,r);
d[x]=d[x*2]*d[x*2+1];
}
matrix query(int x,int l,int r,int t,int k){
if(l==t&&r==k)return d[x];
int mid=(l+r)/2;
if(mid>=k)return query(x*2,l,mid,t,k);
else if(t>mid)return query(x*2+1,mid+1,r,t,k);
else return query(x*2,l,mid,t,mid)*query(x*2+1,mid+1,r,mid+1,k);
}
matrix ask(int u){
return query(1,1,n,pos[top[u]],ed[top[u]]);
}
void change(int x,int l,int r,int t){
if(l==r){
d[x]=val[l];return;
}
int mid=(l+r)/2;
if(mid>=t)change(x*2,l,mid,t);
else change(x*2+1,mid+1,r,t);
d[x]=d[x*2]*d[x*2+1];
}
void change(int u,int x){
val[pos[u]].g[1][0]+=x-a[u];a[u]=x;
matrix od,nw;
//puts("-1");
while(u){
//printf("%d %d %d\n",top[u],pos[top[u]],ed[top[u]]);
od=ask(top[u]);
//puts("-1");
change(1,1,n,pos[u]);
nw=ask(top[u]);
u=fa[top[u]];
val[pos[u]].g[0][0]+=max(nw.g[0][0],nw.g[1][0])-max(od.g[0][0],od.g[1][0]);
val[pos[u]].g[0][1]=val[pos[u]].g[0][0];
val[pos[u]].g[1][0]+=nw.g[0][0]-od.g[0][0];
}
}
int main(){
int t1,i,t,k,u,x;
matrix T;
scanf("%d%d",&n,&t1);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=1;i<n;i++){
scanf("%d%d",&t,&k);
build(t,k);build(k,t);
}
init();
bt(1,1,n);
while(t1--){
scanf("%d%d",&u,&x);
change(u,x);
// puts("-1");
T=ask(1);
printf("%lld\n",max(T.g[0][0],T.g[1][0]));
}
}