求调30pts,码风清晰,部分封装,观感良好,只是不能AC
查看原帖
求调30pts,码风清晰,部分封装,观感良好,只是不能AC
241544
ShineQ楼主2020/11/11 14:30
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(register int i=a,i##end=b;i<=i##end;i++)
#define drep(i,a,b) for(register int i=a,i##end=b;i>=i##end;i--)
#define erep(i,x) for(int i=head[x];i;i=nxt[i])
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
using namespace std;
const int M=100005,inf=1e9;
int n,m,tot,etot;
int A[M],pos[M],L[M],R[M],top[M],size[M],son[M],fa[M];
int g[M][2],f[M][2];
int head[M],E[M<<1],nxt[M<<1];
inline void add(int u,int v){
	E[++etot]=v,nxt[etot]=head[u];
	head[u]=etot;
}
struct martix {
	int A[2][2];
	void set(int pos){
		A[0][0]=g[pos][0],A[0][1]=g[pos][1];
		A[1][0]=g[pos][0],A[1][1]=-inf;
	}
	void reset() {
		rep(i,0,1)rep(j,0,1)A[i][j]=-inf;
	}
	martix operator *(const martix &a)const {
		martix ans;ans.reset();
		rep(i,0,1)rep(j,0,1)rep(k,0,1)ans.A[i][k]=max(ans.A[i][k],A[i][j]+a.A[j][k]);
		return ans;
	}
};
struct seg {
	martix t[M<<2];
	#define ls p<<1
	#define rs p<<1|1
	void build(int p,int l,int r){
		if(l==r){t[p].set(pos[l]);return ;}
		int mid=l+r>>1;
		build(ls,l,mid),build(rs,mid+1,r);
		t[p]=t[ls]*t[rs];
	}
	void update(int p,int l,int r,int x){
		if(l==r){t[p].set(pos[l]);return ;}
		int mid=l+r>>1;
		if(x<=mid)update(ls,l,mid,x);
		else update(rs,mid+1,r,x);
		t[p]=t[ls]*t[rs];
	}
	martix query(int p,int pl,int pr,int l,int r){
		if(pl==l&&pr==r)return t[p];
		int mid=pl+pr>>1;
		if(r<=mid)return query(ls,pl,mid,l,r);
		else if(l>mid)return query(rs,mid+1,pr,l,r);
		else return query(ls,pl,mid,l,mid)*query(rs,mid+1,pr,mid+1,r);
	}
}T;
void upd(int x,int w){
	f[x][1]+=w-A[x],g[x][1]+=w-A[x];
	A[x]=w;
	while(x){
//		printf("x=%d,top=%d\n",x,top[x]);
		martix old=T.query(1,1,n,L[top[x]],R[top[x]]);
		T.update(1,1,n,L[x]);
		martix now=T.query(1,1,n,L[top[x]],R[top[x]]);
		int up=fa[top[x]];
		g[up][0]-=max(old.A[0][0],old.A[0][1]);
		g[up][0]+=max(now.A[0][0],now.A[0][1]);
		g[up][1]-=old.A[0][0];
		g[up][1]+=now.A[0][0];
		x=up;
	}
}
void dfs1(int x,int fat){
	fa[x]=fat,size[x]=1;
	erep(i,x){
		int to=E[i];
		if(to==fat)continue;
		dfs1(to,x);
		size[x]+=size[to];
		if(size[to]>size[son[x]])son[x]=to;
	}
}
void dfs2(int x,int tp){
	g[x][0]=0,g[x][1]=A[x];
	top[x]=tp;
	pos[L[x]=++tot]=x;
	if(son[x]){
		dfs2(son[x],tp);
		R[x]=R[son[x]];
	}else R[x]=tot;
	erep(i,x){
		int to=E[i];
		if(to==fa[x]||to==son[x])continue;
		dfs2(to,to);
		g[x][0]+=max(f[to][0],f[to][1]);
		g[x][1]+=f[to][0];
	}
	if(son[x]){
		f[x][0]=g[x][0]+max(f[son[x]][0],f[son[x]][1]);
		f[x][1]=g[x][1]+f[son[x]][0];
	}else f[x][0]=g[x][0],f[x][1]=g[x][1];
}
int main() {
//	freopen("test.in","r",stdin);
//	freopen("data.out","w",stdout);
	n=read(),m=read();
	rep(i,1,n)A[i]=read();
	rep(i,1,n-1){
		int u=read(),v=read();
		add(u,v),add(v,u);
	}
	dfs1(1,0),dfs2(1,1);
	T.build(1,1,n);
	rep(i,1,m){
		int x=read(),w=read();
		upd(x,w);
		martix res=T.query(1,1,n,L[1],R[1]);
		printf("%d\n",max(res.A[0][0],res.A[0][1]));
	}
	return 0;
}
/*
f[i][0/1] i的子树,i 不选/选的最大值
g[i][0/1] i的子树除去重儿子

f[i][0]=g[i][0]+max(f[son][0],f[son][1])
f[i][1]=g[i][1]+f[son][0]
g[i][0]=∑max f[to][0/1]
g[i][1]=∑f[to][0]
 
构造一个2*2矩阵
使得 [f(son,0),f(son,1)]->[f(i,0),f(i,1)]
g[i][0] g[i][1]
g[i][0] -inf

用树剖更新,一段链可以用矩乘算出top的f矩阵,再更新f[top]的g矩阵。
 
*/
2020/11/11 14:30
加载中...