https://www.cnblogs.com/RabbitHu/p/9112811.html
f
[
i
]
[
1
]
f[i][1]
f[i][1]为选点
i
i
i的最大权独立集。
f
[
i
]
[
0
]
f[i][0]
f[i][0]为不选
i
i
i的最大权独立集。
g
[
u
]
[
0
]
g[u][0]
g[u][0]为轻儿子都不选的最大值。
g
[
u
]
[
1
]
g[u][1]
g[u][1]为轻儿子可以选的最大值
[
f
[
v
]
[
0
]
,
f
[
v
]
[
1
]
]
×
[
g
[
u
]
[
1
]
g
[
u
]
[
0
]
+
v
a
l
[
u
]
g
[
u
]
[
1
]
−
∞
]
=
[
f
[
u
]
[
0
]
,
f
[
u
]
[
1
]
]
\begin{bmatrix}f[v][0],f[v][1]\end{bmatrix} \times \begin{bmatrix}g[u][1]&g[u][0]+val[u]\\g[u][1]& -\infty\end{bmatrix}=\begin{bmatrix}f[u][0],f[u][1]\end{bmatrix}
[f[v][0],f[v][1]]×[g[u][1]g[u][1]g[u][0]+val[u]−∞]=[f[u][0],f[u][1]]
然后乘法换为+,加法换为取max。
LCT日常维护,
g
g
g为虚子树,求链上不满足交换律的积。
AC Code:
#include<bits/stdc++.h>
#define maxn 100005
#define inf 0x3f3f3f3f
using namespace std;
int n,m,val[maxn];
struct mat{
int a[2][2];
mat (int d=0){a[0][0]=a[1][1]=d,a[0][1]=a[1][0]=-inf;}
mat operator *(const mat &B)const{
mat ret(-inf);
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
ret.a[i][k] = max(ret.a[i][k] , a[i][j] + B.a[j][k]);
return ret;
}
};
namespace LCT{
int ch[maxn][2],fa[maxn];
mat g[maxn],s[maxn];
#define il inline
#define pa fa[x]
il int inr(int x){ return ch[pa][1]==x; }
il int isr(int x){ return ch[pa][0]!=x&&ch[pa][1]!=x; }
il void upd(int x){
s[x] = s[ch[x][1]] * g[x] * s[ch[x][0]];
}
il void rot(int x){
int y=fa[x],z=fa[y],c=inr(x);
if(!isr(y)) ch[z][inr(y)]=x;
(ch[y][c]=ch[x][!c])&&(fa[ch[y][c]]=y);
fa[fa[ch[x][!c]=y]=x]=z;
upd(y);
}
il void splay(int x){
for(;!isr(x);rot(x))
if(!isr(pa)) rot(inr(pa)==inr(x)?pa:x);
upd(x);
}
il int access(int x,int y=0){
for(;x;x=fa[y=x]){
splay(x);
if(ch[x][1]){
int a0 = max(s[ch[x][1]].a[0][0],s[ch[x][1]].a[1][0]),
a1 = max(s[ch[x][1]].a[0][1],s[ch[x][1]].a[1][1]);
g[x].a[0][0] += max(a0,a1);
g[x].a[1][0] += max(a0,a1);
g[x].a[0][1] += a0;
}
if(y){
int a0 = max(s[y].a[0][0],s[y].a[1][0]),
a1 = max(s[y].a[0][1],s[y].a[1][1]);
g[x].a[0][0] -= max(a0,a1);
g[x].a[1][0] -= max(a0,a1);
g[x].a[0][1] -= a0;
}
ch[x][1] = y , upd(x);
}
return y;
}
}
using namespace LCT;
int info[maxn],Prev[maxn<<1],to[maxn<<1],cnt_e;
void Node(int u,int v){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }
void dfs(int now,int ff){
fa[now] = ff , g[now].a[0][0] = 0 ,
g[now].a[0][1] = val[now] , g[now].a[1][0] = 0 , g[now].a[1][1] = -inf;
for(int i=info[now];i;i=Prev[i])
if(to[i]!=ff){
dfs(to[i],now);
int a0 = max(s[to[i]].a[0][0],s[to[i]].a[1][0]),
a1 = max(s[to[i]].a[0][1],s[to[i]].a[1][1]);
g[now].a[0][0] += max(a0,a1);
g[now].a[1][0] += max(a0,a1);
g[now].a[0][1] += a0;
}
upd(now);
/*printf("%d\n",now);
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
printf("s[%d][%d] = %d\n",i,j,s[now].a[i][j]);*/
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
Node(u,v),Node(v,u);
}
dfs(1,0);
for(int i=1;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
access(x),splay(x);
g[x].a[0][1] += y - val[x];
val[x] = y;
upd(x);
printf("%d\n",max(max(s[x].a[0][0],s[x].a[0][1]),max(s[x].a[1][0],s[x].a[1][1])));
}
}
全局平衡二叉树:
#include<bits/stdc++.h>
#define maxn 1000006
#define inf 0x3f3f3f3f
#define il inline
#define pa fa[x]
using namespace std;
char cb[1<<18],*cs=cb,*ct=cb,wb[35000005],*wt=wb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<18,stdin),cs==ct)?0:*cs++)
void read(int &res){
char ch;bool f=0;
for(;!isdigit(ch=getc());) if(ch=='-') f=1;
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
if(f) res = -res;
}
inline void write(int x){
int p[12],len=0;//x>=0
while(x) p[++len]=x%10,x/=10;
if(!len) *wt++='0';
else while(len) *wt++=p[len--]+'0';
}
struct mat{
int a,b,c,d;
mat (int p=-inf){ a = d = p , b = c = -inf; }
mat operator *(const mat &B)const{
mat ret;
ret.a = max(a+B.a,b+B.c);
ret.b = max(a+B.b,b+B.d);
ret.c = max(c+B.a,d+B.c);
ret.d = max(c+B.b,d+B.d);
return ret;
}
}f[maxn],g[maxn];
int info[maxn],Prev[maxn<<1],to[maxn<<1],cnt_e;
void Node(int u,int v){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }
int n,m,rt;
int fa[maxn],ch[maxn][2],v[maxn];
int isr(int x){ return ch[pa][0] != x && ch[pa][1] != x; }
int siz[maxn],son[maxn];
void dfs1(int u,int ff){
siz[u] = 1;
for(int i=info[u],v;i;i=Prev[i])
if((v=to[i]) != ff){
dfs1(v,u);
siz[u]+=siz[v];
if(son[u] == 0 || siz[v] > siz[son[u]]) son[u] = v;
}
}
int ar[maxn];
il void upd(int u){ f[u] = f[ch[u][1]] * g[u] * f[ch[u][0]]; }
int Build(int l,int r){
if(l>r) return 0;
int L=l,R=r,mid;
for(;L<R;){
mid = (L+R+1) >> 1;
if((siz[ar[mid]] - siz[ar[r+1]]) * 2 >= (siz[ar[l]]-siz[ar[r+1]])) L = mid;
else R = mid - 1;
}
fa[ch[ar[L]][0] = Build(l,L-1)] = ar[L] , fa[ch[ar[L]][1] = Build(L+1,r)] = ar[L] , fa[0] = 0;
upd(ar[L]);
return ar[L];
}
void dfs2(int u,int ff){
for(int p=u,e=ff;p;p=son[e=p])
for(int i=info[p];i;i=Prev[i])
if(to[i] != e && to[i] != son[p])
dfs2(to[i],p);
int len = 0;
for(int p=u;p;p=son[p]) ar[++len] = p; ar[len+1] = 0;
int w;
fa[w = Build(1,len)] = ff;
if(!ff) rt = w;
if(ff){
int a0 = max(f[w].a,f[w].c) , a1 = max(f[w].b,f[w].d);
g[ff].a+=max(a0,a1),g[ff].b+=a0,g[ff].c+=max(a0,a1);
}
}
int main(){
read(n),read(m);
for(int i=1;i<=n;i++) read(v[i]),g[i].a=g[i].c=0,g[i].d=-inf,g[i].b=v[i];
g[0] = f[0] = mat(0);
for(int i=1,u,y;i<n;i++) read(u),read(y),Node(u,y),Node(y,u);
dfs1(1,0),dfs2(1,0);
for(int lst=0,x,y;m--;){
read(x),read(y);x^=lst;
g[x].b += y - v[x] , v[x] = y;
for(;x;x=pa){
if(isr(x) && pa){
int a0 = max(f[x].a,f[x].c) , a1 = max(a0,max(f[x].b,f[x].d));
g[pa].a-=a1,g[pa].b-=a0,g[pa].c-=a1;
}
upd(x);
if(isr(x) && pa){
int a0 = max(f[x].a,f[x].c) , a1 = max(a0,max(f[x].b,f[x].d));
g[pa].a+=a1,g[pa].b+=a0,g[pa].c+=a1;
}
}
write(lst=max(f[rt].a,max(f[rt].b,max(f[rt].c,f[rt].d)))),*wt++='\n';
}
fwrite(wb,wt-wb,1,stdout);
}