全RE,样例加压缩包样例全过?
查看原帖
全RE,样例加压缩包样例全过?
635829
D_FANG楼主2024/11/24 15:23
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2e5+1e4;
long long my_max(const long long x,const long long y){
	return x>y?x:y;
}
long long my_min(const long long x,const long long y){
	return x<y?x:y;
}
const long long inf=1e18;
struct trees{
	struct tre{
		long long l,r;
		long long plz,val,sum;
	}tree[4*N];
	void push_up(int i){
		tree[i].val=my_max(tree[i*2].val,tree[i*2+1].val);
		tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
	}
	void push_down(int i){
		if (tree[i].plz==0) return ;
		tree[i*2].val+=tree[i].plz;
		tree[i*2+1].val+=tree[i].plz;
		tree[i*2].plz+=tree[i].plz;
		tree[i*2+1].plz+=tree[i].plz;
		tree[i*2].sum+=(tree[i*2].r-tree[i*2].l+1)*tree[i].plz;
		tree[i*2+1].sum+=(tree[i*2+1].r-tree[i*2+1].l+1)*tree[i].plz;
		tree[i].plz=0;
		return ;
	}
	void build(int i,int l,int r){
		tree[i].l=l;tree[i].r=r;tree[i].plz=0;tree[i].val=0;tree[i].sum=0;
		if (l==r){
			return ;
		}
		int mid=(l+r)>>1;
		build(i*2,l,mid);
		build(i*2+1,mid+1,r);
		return ;
	}
	void add(int i,int l,int r,long long val){
		if (tree[i].l>=l&&tree[i].r<=r){
			tree[i].val+=val;
			tree[i].plz+=val;
			tree[i].sum+=(tree[i].r-tree[i].l+1)*val;
			return ;
		}
		if (tree[i].l>r||tree[i].r<l) return ;
		push_down(i);
		if (tree[i*2].r>=l) add(i*2,l,r,val);
		if (tree[i*2+1].l<=r) add(i*2+1,l,r,val);
		push_up(i);
		return ;
	}
	long long query_maxn(int i,int l,int r){
		if (tree[i].l>=l&&tree[i].r<=r) return tree[i].val;
		if (tree[i].l>r||tree[i].r<l) return -inf;
		long long s=-inf;
		push_down(i);
		if (tree[i*2].r>=l) s=query_maxn(i*2,l,r);
		if (tree[i*2+1].l<=r) s=my_max(query_maxn(i*2+1,l,r),s);
		return s;
	}
	long long query_sum(int i,int l,int r){
		if (tree[i].l>=l&&tree[i].r<=r) return tree[i].sum;
		if (tree[i].l>r||tree[i].r<l) return 0;
		long long s=0;
		push_down(i);
		if (tree[i*2].r>=l) s=query_sum(i*2,l,r);
		if (tree[i*2+1].l<=r) s+=query_sum(i*2+1,l,r);
		return s;
	}
	void change(int i,int pos,long long val){
		if (tree[i].l==tree[i].r){
			tree[i].val=val;
			tree[i].sum=val;
			return ;
		}
		if (tree[i*2].r>=pos) change(i*2,pos,val);
		else change(i*2+1,pos,val);
		push_up(i);
		return ;
	}
	void change_val(int i,int pos,long long val){
		if (tree[i].l==tree[i].r){
			tree[i].val=val;
			return ;
		}
		if (tree[i*2].r>=pos) change_val(i*2,pos,val);
		else change_val(i*2+1,pos,val);
		push_up(i);
		return ;
	}
	void change_sum(int i,int pos,long long val){
		if (tree[i].l==tree[i].r){
			tree[i].sum=val;
			return ;
		}
		if (tree[i*2].r>=pos) change_sum(i*2,pos,val);
		else change_sum(i*2+1,pos,val);
		push_up(i);
		return ;
	}
}t1,t2,t3;
int n,q;
struct rec{
	int e,nex;
	long long d;
}z[N*2];
int en,fi[N];
void add(int s,int e,long long d){
	z[++en].e=e;
	z[en].d=d;
	z[en].nex=fi[s];
	fi[s]=en;
}
long long a[N],b[N],c[N],maxn[N],d[N],m3[N],v[N],e[N];
int fa[N],deep[N],siz[N],son[N],id[N],tot,toop[N];
void dfs1(int s,int f,long long sum){
	fa[s]=f;
	deep[s]=deep[f]+1;
	siz[s]=1;
	son[s]=-1;
	for (int i=fi[s];i!=0;i=z[i].nex){
		if (z[i].e==f) continue;
		dfs1(z[i].e,s,sum+z[i].d);
		maxn[s]=my_max(maxn[s],maxn[z[i].e]-2*z[i].d);
		d[z[i].e]=z[i].d;
		siz[s]+=siz[z[i].e];
		if (son[s]==-1||siz[son[s]]<siz[z[i].e]) son[s]=z[i].e;
	}
	m3[s]=maxn[s]+2*sum;
}
void dfs2(int s,int topp){
	toop[s]=topp;
	id[s]=++tot;
	a[id[s]]=maxn[s];
	b[id[s]]=d[s];
	c[id[s]]=m3[s];
	e[id[s]]=v[s];
	if (son[s]==-1) return ;
	dfs2(son[s],topp);
	for (int i=fi[s];i!=0;i=z[i].nex){
		if (z[i].e!=son[s]&&z[i].e!=fa[s]) dfs2(z[i].e,z[i].e);
	}
}
int q_lca(int x,int y,long long &s){
	while (toop[x]!=toop[y]){
		if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
		s-=t2.query_sum(1,id[toop[x]],id[x]);
		x=fa[toop[x]];
	}
	if (id[x]>id[y]) swap(x,y);
	if (id[x]!=id[y]){
		s-=t2.query_sum(1,id[x]+1,id[y]);
	}
	return deep[x]>deep[y]?y:x;
}
void q_sum(int x,int y,long long &s){
	while (toop[x]!=toop[y]){
		if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
		s+=t2.query_sum(1,id[toop[x]],id[x]);
		x=fa[toop[x]];
	}
	s+=t2.query_sum(1,min(id[x],id[y]),max(id[x],id[y]));
	return ;
}
void q_ans_t1(int x,int y,long long &s){
	while (toop[x]!=toop[y]){
		if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
		s=my_max(s,t1.query_maxn(1,id[toop[x]],id[x]));
		x=fa[toop[x]];
	}
	s=my_max(s,t1.query_maxn(1,min(id[x],id[y]),max(id[x],id[y])));
	return ;
}
void q_ans_t2(int x,int y,long long &s){
	while (toop[x]!=toop[y]){
		if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
		s=my_max(s,t2.query_maxn(1,id[toop[x]],id[x]));
		x=fa[toop[x]];
	}
	s=my_max(s,t2.query_maxn(1,min(id[x],id[y]),max(id[x],id[y])));
	return ;
}
void c_add(int x,int y,long long op){
	long long sum=0;
	q_sum(x,y,sum);
	sum*=op;
	while (toop[x]!=toop[y]){
		if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
		t3.add(1,id[toop[x]],id[x],sum);
		x=fa[toop[x]];
	}
	if (id[x]>id[y]) swap(x,y);
	t3.add(1,id[x],id[y],sum);
	return ;
}
void q_ans_t3(int x,int y,long long &s){
	while (toop[x]!=toop[y]){
		if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
		s=my_max(s,t3.query_maxn(1,id[toop[x]],id[x]));
		x=fa[toop[x]];
	}
	s=my_max(s,t3.query_maxn(1,min(id[x],id[y]),max(id[x],id[y])));
	return ;
}
void init(){
	scanf("%lld%lld",&n,&q);
	for (int i=1;i<=n;++i){
		scanf("%lld",&maxn[i]);
		v[i]=maxn[i];
	}
	for (int i=1;i<n;++i){
		int s,e;
		long long d;
		scanf("%d%d%lld",&s,&e,&d);
		add(s,e,d);
		add(e,s,d);
	}
	dfs1(1,0,0);
	dfs2(1,1);
	t1.build(1,1,n);
	t2.build(1,1,n);
	t3.build(1,1,n);
	for (int i=1;i<=n;++i){
		t1.change(1,i,a[i]);
		t3.change(1,i,c[i]);
		t2.change_sum(1,i,b[i]);
		t2.change_val(1,i,e[i]);
	}
}
void work(){
	int x,y,lca;
	long long ans,s;
	for (int i=1;i<=q;++i){
		scanf("%d%d",&x,&y);
		ans=0;s=-inf;
		lca=q_lca(x,y,ans);
		ans+=v[x]+v[y];
		q_ans_t1(x,y,s);
		q_ans_t2(x,y,s);
		
		c_add(1,lca,-2);
		q_ans_t3(1,lca,s);
		c_add(1,lca,2);
		
		ans+=s;
		printf("%lld\n",ans);
	}
}
int main(){
	init();
	work();
	return 0;
}
2024/11/24 15:23
加载中...