不想丸辣!WA 0pts 求调 悬关
查看原帖
不想丸辣!WA 0pts 求调 悬关
1173109
OrientDragon楼主2025/8/4 22:44

事实上在小样例输入的时候这个程序的输出是一堆负无穷。

#include<bits/stdc++.h>
using namespace std;

const int N=100005,inf=0x3f3f3f3f;
int n,m,cnt,rnk[N],g[N][2],f[N][2];
vector<int>e[N];

struct matrix{
	int l1,l2,a[3][3];
	matrix(){
		l1=l2=2;
		a[1][1]=a[1][2]=a[2][1]=a[2][2]=-inf;
	}
};

matrix operator*(matrix a,matrix b){
	matrix c;
	c.l1=a.l1,c.l2=b.l2;
	for(int i=1;i<=c.l1;i++)
		for(int j=1;j<=c.l2;j++)
			for(int k=1;k<=a.l2;k++)
				c.a[i][j]=max(c.a[i][j],a.a[i][k]+b.a[k][j]);
	return c;
}

struct SegTree{
	int l,r;
	matrix mul;
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define mul(x) tree[x].mul
}tree[N<<3];

struct node{
	int siz,fa,top,id,son,dep,val,bottom;
	node(){
		siz=fa=top=id=son=dep=val=bottom=0;
	}
}a[N];

void dfs1(int u,int f){
	a[u].fa=f;
	a[u].dep=a[f].dep+1;
	a[u].siz=1;
	int mx=0;
	for(int v:e[u]){
		if(v==f)continue;
		dfs1(v,u);
		a[u].siz+=a[v].siz;
		if(a[v].siz>mx){
			mx=a[v].siz;
			a[u].son=v;
		}
	}
}

void dfs2(int u,int f){
	a[u].top=f;
	a[u].id=++cnt;
	rnk[cnt]=u;
	if(!a[u].son)return a[u].bottom=u,void();
	dfs2(a[u].son,f);
	a[u].bottom=a[ a[u].son ].bottom;
	for(int v:e[u]){
		if(v==a[u].fa||v==a[u].son)continue;
		dfs2(v,v);
	}
}

void build(int u){
	g[u][1]=a[u].val;
	for(int v:e[u]){
		if(v==a[u].fa)continue;
		build(v);
		if(v==a[u].son)continue;
		g[u][1]+=f[v][0];
		g[u][0]+=max(f[v][1],f[v][0]);
	}
	f[u][1]=g[u][1]+f[ a[u].son ][0];
	f[u][0]=g[u][0]+max(f[ a[u].son ][0],f[ a[u].son ][1]);
	matrix ret;
	ret.a[1][1]=ret.a[1][2]=g[u][0];
	ret.a[2][1]=g[u][1];
	mul(a[u].id)=ret;
}

void pushup(int x){
	mul(x)=mul(x<<1)*mul(x<<1|1);
}

void build2(int x,int l,int r){
	l(x)=l,r(x)=r;
	if(l==r)return;
	int mid=l+r>>1;
	build2(x<<1,l,mid);
	build2(x<<1|1,mid+1,r);
	pushup(x);
}

void modify(int x,int pos){
	int l=l(x),r=r(x);
	if(l==r){
		int t=rnk[pos];
		mul(x).a[1][1]=mul(x).a[1][2]=g[t][0];
		mul(x).a[2][1]=g[t][1];
		return;
	}
	int mid=l+r>>1;
	if(pos<=mid)modify(x<<1,pos);
	else modify(x<<1|1,pos);
	pushup(x);
}

matrix query(int x,int askl,int askr){
	int l=l(x),r=r(x);
	if(askl>askr){
		matrix ret;
		ret.a[1][1]=ret.a[2][2]=0;
		return ret;
	}
	if(askl<=l&&r<=askr)
		return mul(x);
	int mid=l+r>>1;
	matrix ret;
	ret.a[1][1]=ret.a[2][2]=0;
	if(askl<=mid)ret=ret*query(x<<1,askl,askr);
	if(askr>mid)ret=ret*query(x<<1|1,askl,askr);
	return ret;
}

void change(int x,int val){
	g[x][1]+=val-a[x].val;
	a[x].val=val;
	modify(1,a[x].id);
	x=a[x].top;
	while(x!=1){
		matrix ret;
		ret.l2=1;
		ret.a[1][1]=0,ret.a[2][1]=a[ a[x].bottom ].val;
		ret=query(1,a[x].id,a[ a[x].bottom ].id-1)*ret;
		int fx0=f[x][0],fx1=f[x][1];
		f[x][0]=ret.a[1][1];
		f[x][1]=ret.a[2][1];
		g[ a[x].fa ][0]+=max(f[x][0],f[x][1])-max(fx0,fx1);
		g[ a[x].fa ][1]+=f[x][0]-fx0;
		modify(1,a[ a[x].fa ].id);
		x=a[ a[x].fa ].top;
	}
}

int fquery(int top){
	int bottom=a[top].bottom;
	matrix ret;
	ret.l2=1;
	ret.a[1][1]=0,ret.a[2][1]=a[bottom].val;
	if(a[bottom].id-1>=a[top].id)
		ret=query(1,a[top].id,a[bottom].id-1)*ret;
	return max(ret.a[1][1],ret.a[2][1]);
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i].val;
	for(int i=1,u,v;i<n;i++){
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1);
	build2(1,1,cnt);
	for(int i=1,u,v;i<=m;i++){
		cin>>u>>v;
		change(u,v);
		cout<<fquery(1)<<'\n';
	}
}
2025/8/4 22:44
加载中...