千古谜题求助,不管怎么改都是WA,求调QAQ
查看原帖
千古谜题求助,不管怎么改都是WA,求调QAQ
238948
lzp101001楼主2022/5/8 21:10
#include<bits/stdc++.h>
#define ll long long
#define inf 4557430888798830399
using namespace std;
const ll N=100010,M=N*2;
const ll NUM=1e18;
ll n,m;
ll a[N];
ll h[N],e[M],ne[M],idx;
ll d[N],sz[N],fa[N],son[N];
ll id[N],na[N],top[N],cnt;
struct nd{
	ll l,r;
	ll sum,tmax,lmax,rmax;
	ll tag;
}tr[N*4];
void adds(ll a,ll b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs1(ll u,ll father,ll dep){
	d[u]=dep,sz[u]=1,fa[u]=father;
	for(ll i=h[u];~i;i=ne[i]){
		ll v=e[i];
		if(v==father) continue;
		dfs1(v,u,dep+1);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u]=v;
	}
}
void dfs2(ll u,ll t){
	id[u]=++cnt,na[cnt]=a[u],top[u]=t;
	if(!son[u]) return;
	dfs2(son[u],t);
	for(ll i=h[u];~i;i=ne[i]){
		ll v=e[i];
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}
void merge(nd &root,nd &left,nd &right){
	root.sum=left.sum+right.sum;
	root.lmax=left.lmax;
	if(left.tmax==left.sum) root.lmax=max(root.lmax,left.sum+right.lmax);
	root.rmax=right.rmax;
	if(right.tmax==right.sum) root.rmax=max(root.rmax,right.sum+left.rmax);
	root.tmax=max(max(left.tmax,right.tmax),left.rmax+right.lmax);
}
void pushup(ll u){
	merge(tr[u],tr[u<<1],tr[u<<1|1]);
}
void change_to(nd &t,ll k){
	t.sum=k*(t.r-t.l+1);
	t.lmax=t.rmax=t.tmax=max(k*(t.r-t.l+1),k);
	t.tag=k;
}
void pushdown(ll u){
	nd &root=tr[u],&left=tr[u<<1],&right=tr[u<<1|1];
	if(root.tag!=NUM){
		change_to(left,root.tag),change_to(right,root.tag);
		root.tag=NUM;
	}
}
void build(ll u,ll l,ll r){
	tr[u]={l,r,na[r],na[r],na[r],na[r],NUM};
	if(l==r) return;
	ll mid=l+r>>1;
	build(u<<1,l,mid),build(u<<1|1,mid+1,r);
	pushup(u);
}
void update(ll u,ll l,ll r,ll k){
	if(l<=tr[u].l&&tr[u].r<=r){
		change_to(tr[u],k);
		return;
	}
	pushdown(u);
	ll mid=tr[u].l+tr[u].r>>1;
	if(l<=mid) update(u<<1,l,r,k);
	if(r>mid) update(u<<1|1,l,r,k);
	pushup(u);
}
nd query(ll u,ll l,ll r){
	if(l<=tr[u].l&&tr[u].r<=r){
		return tr[u];
	}
	pushdown(u);
	ll mid=tr[u].l+tr[u].r>>1;
	if(r<=mid) return query(u<<1,l,r);
	if(l>mid) return query(u<<1|1,l,r);
	nd root,left=query(u<<1,l,r),right=query(u<<1|1,l,r);
	merge(root,left,right);
	return root;
}
void update_path(ll u,ll v,ll k){
	while(top[u]!=top[v]){
		if(d[top[u]]<d[top[v]]) swap(u,v);
		update(1,id[top[u]],id[u],k);
		u=fa[top[u]];
	}
	if(d[u]<d[v]) swap(u,v);
	update(1,id[v],id[u],k);
}
nd query_path(ll u,ll v){
	bool vis1=0,vis2=0;
	nd left,right;
	while(top[u]!=top[v]){
		if(d[top[u]]>d[top[v]]){
			nd t=query(1,id[top[u]],id[u]);  
			nd tleft=left;
			if(!vis1) left=t,vis1=1;
			else merge(left,t,tleft);
			u=fa[top[u]];
		}else{
			nd t=query(1,id[top[v]],id[v]);
			nd tright=right;
			if(!vis2) right=t,vis2=1;
			else merge(right,t,tright);
			v=fa[top[v]];
		}
	}
	if(d[u]>d[v]){
		nd t=query(1,id[v],id[u]);
		nd tleft=left;
		if(!vis1) left=t,vis1=1;
		else merge(left,t,tleft);
	}else{
		nd t=query(1,id[u],id[v]);
		nd tright=right;
		if(!vis2) right=t,vis2=1;
		else merge(right,t,tright);
	}
	if(!vis1) return right;
	if(!vis2) return left;
	swap(left.lmax,left.rmax);
	nd root;
	merge(root,left,right);
	return root;
}
int main(){
	memset(h,-1,sizeof h);
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	for(ll i=1;i<n;i++){
		ll x,y;
		scanf("%lld%lld",&x,&y);
		adds(x,y),adds(y,x);
	}
	dfs1(1,-1,1);
	dfs2(1,1);
	build(1,1,n);
	scanf("%lld",&m);
	while(m--){
		ll op,x,y,z;
		scanf("%lld",&op);
		if(op==1){
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",max(0ll,query_path(x,y).tmax));
		}else{
			scanf("%lld%lld%lld",&x,&y,&z);
			update_path(x,y,z);
		}
	}
    return 0;
}
2022/5/8 21:10
加载中...