样例过不了
#include <bits/stdc++.h>
#define gc IO::fastgc()
#define pc(c) IO::fastpc(c)
#define printf(x...)
typedef long long ll;typedef long long unsigned llu,ull;typedef long double lf;
using namespace std;
namespace IO{char ibuf[1<<23],obuf[1<<23],*ip1=ibuf,*ip2=ibuf,*o=obuf;inline char fastgc(){return((ip1==ip2)&&(ip2=(ip1=ibuf)+fread(ibuf,1,1<<21,stdin),ip1==ip2)?EOF:*ip1++);}inline void fastpc(char c){(o-obuf<(1<<22))?(*(o++)=c):(fwrite(obuf,o-obuf,1,stdout),o=obuf,*(o++)=c);}struct _{_(){}~_(){fwrite(obuf,o-obuf,1,stdout);}}__;}
template<typename T>inline void read(T &t){t=0;T f=1;char c=gc;while(c!='-'&&(c<'0'||c>'9'))c=gc;if(c=='-')f=-1,c=gc;while(c>='0'&&c<='9')t=10*t+(c&15),c=gc;t*=f;}
template<> inline void read<string>(string &t){t="";char c=gc;while(isspace(c)||c==EOF)c=gc;while(!(isspace(c)||c==EOF))t+=c,c=gc;}
template<> inline void read<char>(char&t){t=gc;while(t==' '||t=='\r'||t=='\t'||t=='\n')t=gc;}
template<typename T>inline void write(T x){if(!x)return(void)pc('0');if(x<0)pc('-'),x=-x;static char c[33]={""};static int cc=0;while(x)c[++cc]=x%10,x/=10;while(cc)pc(c[cc--]|48);}
inline void write(const string &x){for(auto c:x)pc(c);}
inline void write(const char *x){for(;*x;++x)pc(*x);}
inline void write(char _){pc(_);}
template<typename T1,typename ...Args> inline void read(T1 &v1,Args&... args){read(v1),read(args...);}
template<typename T1,typename ...Args> inline void write(const T1 &v1,const Args&... args){write(v1),write(args...);}
/*
普通 dp:
f[u][j]=u点 有/没有 驻扎,子树最小花费
f[u][0]=sum(f[v][1])
f[u][1]=p[u]+sum(max(f[v][0],f[v][1]))
动态 dp:
f[u][j]表示所有点的dp
g[u][j]表示u的子结点中轻链的dp
f[u][0]=g[u][0]+f[hs][1]
f[u][1]=g[u][1]+max(f[hs][0],f[hs][1])
fi0 = INF gi0 * fhs0
fi1 gi1 gi1 fhs1
代码中的g[u]用h[u]表示
*/
constexpr unsigned N=1e5+7,NN=4e5+37,M=2e5+17;
constexpr int INF=0x3f3f3f4f;
int n,m;
vector<int> g[N];
string datatype;
int fa[N],dep[N],sz[N],hs[N],dfn[N],tp[N],ed[N],pos[N],dft;
int f[N][2],h[N][2],p[N];
int htmp[N][2];
struct Matrix{
int a[2][2];
inline void zero(){a[0][0]=a[0][1]=a[1][0]=a[1][1]=INF;}
inline void unit(){a[0][0]=a[1][1]=0,a[0][1]=a[1][0]=INF;}
inline int *operator[](unsigned i){return a[i];}
inline const int *operator[](unsigned j)const{return a[j];}
inline Matrix operator*(const Matrix &b)const{
Matrix c;
c.zero();
for(int k{0};k<2;++k)
for(int i{0};i<2;++i)
for(int j{0};j<2;++j)
c[i][j]=min(c[i][j],a[i][k]+b[k][j]);
return c;
}
};
inline void out(const Matrix &x){
printf("[%d,%d,%d,%d]\n",x[0][0],x[0][1],x[1][0],x[1][1]);
}
struct{
struct{
int l,r;
Matrix x;
}tr[NN];
inline void apply(int k,int u){
auto &m=tr[k].x;
m.zero(),
m[0][1]=h[u][0],
m[1][0]=m[1][1]=h[u][1];
}
inline void pushup(int k){
tr[k].x=tr[k<<1].x*tr[k<<1|1].x;
}
void build(int k,int l,int r){
printf("%d:%d,%d\n",k,l,r);
tr[k].l=l,tr[k].r=r;
if(l==r){
printf("l=%d(%d)\n",l,pos[l]);
apply(k,pos[l]);
printf("m[%d]=",k);out(tr[k].x);
return;
}
int m{(l+r)>>1};
build(k<<1,l,m),
build(k<<1|1,m+1,r),
pushup(k);
printf("m [%d]=",k);out(tr[k].x);
}
void modify(int k,int x){
if(tr[k].l>x||tr[k].r<x) return;
if(tr[k].l==tr[k].r) return apply(k,pos[x]);
modify(k<<1,x),modify(k<<1|1,x),
pushup(k);
}
Matrix query(int k,int l,int r){
Matrix ret;
ret.unit();
if(tr[k].l>r||tr[k].r<l) return ret;
if(tr[k].l>=l&&tr[k].r<=r) return tr[k].x;
return query(k<<1,l,r)*query(k<<1|1,l,r);
}
}seg;
void dfs(int u,int fa){
::fa[u]=fa,
dep[u]=dep[fa]+1,
sz[u]=1;
for(auto v:g[u]){
if(v==fa) continue;
dfs(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[hs[u]]){
hs[u]=v;
}
}
}
void sfd(int u,int fa,int tpn){
pos[dfn[u]=++dft]=u;
tp[u]=tpn;
ed[tpn]=max(ed[tpn],dft);
if(hs[u]){
sfd(hs[u],u,tpn);
}
for(auto v:g[u]){
if(v==fa||v==hs[u]) continue;
sfd(v,u,v);
}
}
void sdf(int u,int fa){
printf("sdf(%d,%d)\n",u,fa);
f[u][0]=h[u][0]=0,
f[u][1]=h[u][1]=p[u];
if(hs[u]){
int v=hs[u];
sdf(v,u);
f[u][0]+=f[v][1];
f[u][1]+=min(f[v][0],f[v][1]);
}
for(auto v:g[u]){
if(v==fa||v==hs[u]) continue;
printf("v=%d\n",v);
sdf(v,u);
f[u][0]+=f[v][1],
f[u][1]+=min(f[v][0],f[v][1]),
h[u][0]+=f[v][1],
h[u][1]+=min(f[v][0],f[v][1]);
}
printf("f[%d]={%d,%d},g[%d]={%d,%d}\n",u,f[u][0],f[u][1],u,h[u][0],h[u][1]);
}
inline void modify(int u,int v){
switch(v){
case -1:{
//-1代表恢复
h[u][0]=htmp[u][0],
h[u][1]=htmp[u][1];
break;
}
case 0:{
h[u][1]=INF;
break;
}
case 1:{
h[u][0]=INF;
break;
}
}
Matrix a,b;
while(u){
a=seg.query(1,dfn[tp[u]],ed[tp[u]]);
seg.modify(1,dfn[u]);
b=seg.query(1,dfn[tp[u]],ed[tp[u]]);
u=fa[tp[u]];
h[u][0]+=max(b[0][0],b[1][0])-max(a[0][0],a[1][0]);
h[u][1]+=b[0][0]-a[0][0];
}
}
inline int query(){
Matrix x=seg.query(1,dfn[1],ed[1]);
int t=min(x[0][0],x[1][0]);
if(t==INF) return -1;
return t;
}
signed main(){
read(n,m,datatype);
(void)datatype;
for(int i{1};i<=n;++i){
read(p[i]);
}
for(int i{1};i<n;++i){
int u,v;
read(u,v);
g[u].emplace_back(v),
g[v].emplace_back(u);
}
dfs(1,0),
sfd(1,0,1),
sdf(1,0);
memcpy(htmp,h,sizeof h);
seg.build(1,1,dft);
printf("dfa\n");
printf("%d %d\n",min(f[1][0],f[1][1]),query());
while(m--){
int a,x,b,y;
read(a,x,b,y);
modify(a,x);
modify(b,y);
write(query(),'\n');
modify(a,-1),
modify(b,-1);
}
return 0;
}
题解里甚至没有同样写法的