专栏文章

2025-11-25

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@min0qiqa
此快照首次捕获于
2025/12/01 18:40
3 个月前
此快照最后确认于
2025/12/01 18:40
3 个月前
查看原文
人生中第一个10k+的代码!
CPP
#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define lc (u<<1)
#define rc (u<<1|1)
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define fst first
#define sed second
#define Max(a,b) ((a)<(b)?(a)=(b):1)
#define Min(a,b) ((a)>(b)?(a)=(b):1)
using namespace std;
const int N=1e5+10,inf=1e18;
namespace Fread{const int SIZE=1<<21;char buf[SIZE],*S,*T;inline char getchar(){if(S==T){T=(S=buf)+fread(buf,1,SIZE,stdin);if(S==T)return'\n';}return *S++;}}
namespace Fwrite{const int SIZE=1<<21;char buf[SIZE],*S=buf,*T=buf+SIZE;inline void flush(){fwrite(buf,1,S-buf,stdout);S=buf;}
inline void putchar(char c){*S++=c;if(S==T)flush();}struct POPOSSIBLE{~POPOSSIBLE(){flush();}}ztr;}
#define getchar Fread ::getchar
#define putchar Fwrite ::putchar
namespace Fastio{struct Reader{template<typename T>Reader&operator>>(T&x){char c=getchar();T f=1;while (c<'0'||c>'9'){if (c=='-')f=-1;c=getchar();}x=0;while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}x*=f;return*this;}Reader&operator>>(char&c){c=getchar();while(c==' '||c=='\n')c=getchar();return*this;}Reader&operator>>(char*str){int len=0;char c=getchar();while (c==' '||c=='\n')c=getchar();while(c!=' '&&c!='\n'&&c!='\r'){str[len++]=c;c=getchar();}str[len]='\0';return *this;}Reader&operator>>(string&s){char c=getchar();s.clear();while(c==' '||c=='\n')c=getchar();while(c!=' '&&c!='\n'&&c!='\r'){s+=c;c=getchar();}return*this;}Reader(){}}cin;struct Writer{template<typename T>Writer&operator<<(T x){if(x==0){putchar('0');return *this;}if(x<0){putchar('-');x=-x;}static int sta[45];int top=0;while(x){sta[++top]=x%10;x/=10;}while(top){putchar(sta[top]+'0');--top;}return*this;}Writer&operator<<(char c){putchar(c);return*this;}Writer&operator<<(char*str){int cur=0;while(str[cur])putchar(str[cur++]);return*this;}Writer&operator<<(const char*str){int cur=0;while(str[cur])putchar(str[cur++]);return*this;}Writer(){}}cout;}
#define cin Fastio ::cin
#define cout Fastio ::cout
bool MS;int used,id;
int n,q,L;
int a[N];
int stmax[20][N];
pii st_upper[20][N];
pii st_lower[20][N];
int f[N],g[N];
int h[N];
int ot[N];
vector<int>edge[N];
int son[N];
vector<pii>chain[N]; 
vector<pii>mh[N];
vector<pii>pre[N],suf[N];
vector<int>preh[N],sufh[N];
int st[N],wson[N],deep[N],sz[N],fa[N];
int dept[N];
int dfn[N],rev[N],res;
int lg[N];
inline void merge(pii&u,pii v){
	if(v.fst>u.fst)
	{
		u.sed=u.fst;
		u.fst=v.fst;
	}
	else Max(u.sed,v.fst);
	if(v.sed>u.fst)
	{
		u.sed=u.fst;
		u.fst=v.sed;
	}
	else Max(u.sed,v.sed);
}
void init(){
	res=0;
	memset(f,0,sizeof f);
	memset(g,0,sizeof g);
	memset(h,0,sizeof h);
	memset(ot,0,sizeof ot);
	memset(st,0,sizeof st);
	memset(wson,0,sizeof wson);
	memset(deep,0,sizeof deep);
	memset(sz,0,sizeof sz);
	memset(fa,0,sizeof fa);
	memset(son,0,sizeof son);
	rep(i,1,n)
	{
		edge[i].clear();
		chain[i].clear();
		pre[i].clear();
		suf[i].clear();
		preh[i].clear();
		sufh[i].clear();
		mh[i].clear();
	}
	lg[1]=0;
	rep(i,2,N-1)
	{
		lg[i]=lg[i/2]+1;
	}
}

void dfs1(int u,int fa){
	dept[u]=dept[fa]+a[u];
	deep[u]=deep[fa]+1;
	::fa[u]=fa;
	sz[u]=1;
	pii vl=mp(0,0);
	f[u]=a[u];
	for(auto v:edge[u])
	if(v!=fa)
	{
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[wson[u]])
		wson[u]=v;
		Max(f[u],f[v]+a[u]);
		merge(vl,mp(f[v],0));
		Max(h[u],h[v]);
		mh[u].pb(mp(h[v],v));
	}
	Max(h[u],vl.fst+vl.sed+a[u]);
	sort(mh[u].begin(),mh[u].end());
	reverse(mh[u].begin(),mh[u].end());
}
void dfs2(int u,int fa,int st){
	dfn[u]=++res;
	rev[res]=u;
	::st[u]=st;
	int cnt=0;
	for(auto v:edge[u])
	if(v!=fa&&v!=wson[u])
	{
		son[v]=cnt;cnt++;
		pre[u].pb(mp(f[v],0));
		suf[u].pb(mp(f[v],0));
		preh[u].pb(h[v]);
		sufh[u].pb(h[v]);
		chain[u].pb(mp(f[v],v));
	}
	rep(i,1,cnt-1)
	{
		merge(pre[u][i],pre[u][i-1]);
		Max(preh[u][i],preh[u][i-1]);
	}
	per(i,cnt-2,0)
	{
		merge(suf[u][i],suf[u][i+1]);
		Max(sufh[u][i],sufh[u][i+1]);
	}
	if(wson[u])
	{
		int v=wson[u]; 
		g[v]=g[u]+a[u];
		if(suf[u].size())
		Max(g[v],suf[u][0].fst+a[u]);
		chain[u].pb(mp(f[wson[u]],wson[u]));
		dfs2(wson[u],u,st);
	}
	cnt=0;
	for(auto v:edge[u])
	if(v!=fa&&v!=wson[u])
	{
		g[v]=g[u]+a[u];
		if(wson[u])Max(g[v],f[wson[u]]+a[u]);
		if(cnt)						Max(g[v],pre[u][cnt-1].fst+a[u]);
		if(cnt+1<(int)suf[u].size())Max(g[v],suf[u][cnt+1].fst+a[u]);
		dfs2(v,u,v);
		cnt++;
	}
	if(fa)
	chain[u].pb(mp(g[u],fa));
	sort(chain[u].begin(),chain[u].end());
	reverse(chain[u].begin(),chain[u].end());
}
void dfs3(int u,int fa){
	int cnt=0,res=0;
	if(fa)
	{
		for(auto [val,from]:chain[fa])
		{
			if(from!=u)
			{
				cnt++;
				res+=val;
			}
			if(cnt==2)break;
		}
		Max(ot[u],res+a[fa]);
	}
	if(wson[u])
	{
		int v=wson[u]; 
		ot[v]=ot[u];
		if(suf[u].size())
		Max(ot[v],sufh[u][0]);
		dfs3(wson[u],u);
	}
	cnt=0;
	for(auto v:edge[u])
	if(v!=fa&&v!=wson[u])
	{
		ot[v]=ot[u];
		if(wson[u])Max(ot[v],h[wson[u]]);
		if(cnt)						Max(ot[v],preh[u][cnt-1]);
		if(cnt+1<(int)suf[u].size())Max(ot[v],sufh[u][cnt+1]);
		dfs3(v,u);
		cnt++;
	}
}
int LCA,fu,fv;
int lca(int u,int v){
	if(st[u]==st[v])return dfn[u]<dfn[v]?u:v;
	if(deep[st[u]]>deep[st[v]])swap(u,v);
	return lca(u,fa[st[v]]);
}
int getson(int u,int v){
	if(u==v)return u;
	while(1)
	{
		if(st[u]==st[v])return wson[v];
		u=st[u];
		if(fa[u]==v)return u;
		u=fa[u];
	}
}
int query(int l,int r){
	if(l>r)return 0;
	int g=lg[r-l+1];
	return max(stmax[g][l],stmax[g][r-(1<<g)+1]);
}
pii query_upper(int l,int r){
	int g=lg[r-l+1];
	return max(st_upper[g][l],st_upper[g][r-(1<<g)+1]);
}
pii query_lower(int l,int r){
	int g=lg[r-l+1];
	return max(st_lower[g][l],st_lower[g][r-(1<<g)+1]);
}
int solve1(int u,int v,bool tag=0){
	int ans=0;
	if(tag)
	{
		if(!(dfn[u]<=dfn[v]&&dfn[v]<dfn[u]+sz[u]))Max(ans,h[u]);
		if(!(dfn[v]<=dfn[u]&&dfn[u]<dfn[v]+sz[v]))Max(ans,h[v]);
		Max(ans,ot[LCA]);
		int cnt=0,res=0;
		for(auto [val,from]:chain[LCA])
		{
			if(from!=fu&&from!=fv)
			{
				cnt++;
				res+=val;
			}
			if(cnt==2)break;
		}
		for(auto [val,from]:mh[LCA])
		if(from!=fu&&from!=fv)
		{
			Max(ans,val);
			break;
		}
		Max(ans,res+a[LCA]);
	}
	if(st[u]==st[v])
	{
		int l=min(dfn[u],dfn[v]);
		int r=max(dfn[u],dfn[v]);
		l++;r--;
		Max(ans,query(l,r));
		return ans;
	}
	if(deep[st[u]]>deep[st[v]])swap(u,v);
	Max(ans,query(dfn[st[v]],dfn[v]-1));
	int now=fa[st[v]];
	int pos=son[st[v]];
	if(now!=LCA)
	{
		if(wson[now])					Max(ans,h[wson[now]]);
		if(pos)							Max(ans,preh[now][pos-1]);
		if(pos+1<(int)sufh[now].size())	Max(ans,sufh[now][pos+1]);
		pii val=mp(0,0);
		if(pos)					 		merge(val,pre[now][pos-1]);
		if(pos+1<(int)suf[now].size())	merge(val,suf[now][pos+1]);
		merge(val,mp(f[wson[now]],0));
		Max(ans,val.fst+val.sed+a[now]);
	}
	Max(ans,solve1(u,now));
	return ans;
}
int dis(int u,int v){
	if(!v)return 0;
	else if(dfn[v]<=dfn[u]&&dfn[u]<dfn[v]+sz[v])return dept[u]-dept[fa[v]];
	else return dept[u]+dept[v]-dept[LCA]-dept[fa[LCA]];
}
namespace SGT{
	struct vl
	{
		int premax,sufmax,maxn,sum;
		vl operator+(const vl&b)const
		{
			vl c;
			c.premax=max(premax,  sum+b.premax);
			c.sufmax=max(b.sufmax,b.sum+sufmax);
			c.sum=sum+b.sum;
			c.maxn=max({sufmax+b.premax,maxn,b.maxn});
			return c;
		}
	}tre[N<<2];
	void build(int u,int l,int r)
	{
		if(l==r)
		{
			int now=rev[l];
			tre[u].maxn=tre[u].premax=tre[u].sufmax=tre[u].sum=a[now];
			for(auto [w,from]:chain[now])
			{
				if(from==wson[now]||from==fa[now])continue;
				tre[u].maxn=tre[u].premax=tre[u].sufmax=w+a[now];
				break;
			}
			return;
		}
		int mid=(l+r)/2;
		build(lc,l,mid);
		build(rc,mid+1,r);
		tre[u]=tre[lc]+tre[rc];
	}
	vl query(int u,int l,int r,int x,int y)
	{
		if(x<=l&&r<=y)
		{
			return tre[u];
		}
		int mid=(l+r)/2;
		if(x<=mid&&y>mid)return query(lc,l,mid,x,y)+query(rc,mid+1,r,x,y);
		if(x<=mid)return query(lc,l,mid,x,y);
		return query(rc,mid+1,r,x,y);
	}
}using namespace SGT;
int sufmax[N];
vector<pii>opt;
void get_next(int&v,int&pos){
	if(dfn[v]==opt[pos].sed)
	{
		pos++;
		v=rev[opt[pos].fst];
	}
	else
	{
		if(opt[pos].fst<=opt[pos].sed)
		v=rev[dfn[v]+1];
		else
		v=rev[dfn[v]-1];
	}
}
void get_last(int&v,int&pos){
	if(dfn[v]==opt[pos].fst)
	{
		pos--;
		v=rev[opt[pos].sed];
	}
	else
	{
		if(opt[pos].fst<=opt[pos].sed)
		v=rev[dfn[v]-1];
		else
		v=rev[dfn[v]+1];
	}
}
int nxt(int v,int pos){
	if(dfn[v]==opt[pos].sed)
	{
		pos++;
		v=rev[opt[pos].fst];
	}
	else
	{
		if(opt[pos].fst<=opt[pos].sed)
		v=rev[dfn[v]+1];
		else
		v=rev[dfn[v]-1];
	}
	return v;
}
int lst(int v,int pos){
	if(dfn[v]==opt[pos].fst)
	{
		pos--;
		v=rev[opt[pos].sed];
	}
	else
	{
		if(opt[pos].fst<=opt[pos].sed)
		v=rev[dfn[v]-1];
		else
		v=rev[dfn[v]+1];
	}
	return v;
}
int hu,hv;
int val(int x,int pos){
	int nt=(x==hv?0:nxt(x,pos));
	int lt=(x==hu?0:lst(x,pos));
	for(auto [w,from]:chain[x])
	{
		if((x!=hv&&from==nt)||(x!=hu&&from==lt))continue;
		return w+a[x];
	}
	return a[x];
}
int solve2(int u,int v,int w,bool tag=0)
{
	hu=u,hv=v; 
	opt.clear();
	opt.pb(mp(0,0));
	while(1)
	{
		if(u!=LCA)
		opt.pb(mp(dfn[u],dfn[u]));
		if(st[u]==st[LCA])
		{
			if(u!=LCA&&fa[u]!=LCA)
			opt.pb(mp(dfn[u]-1,dfn[LCA]+1));
			break;
		}
		else
		{
			if(u!=st[u])
			opt.pb(mp(dfn[u]-1,dfn[st[u]]));
			u=fa[st[u]];
		}
	}
	opt.pb(mp(dfn[LCA],dfn[LCA]));
	stack<pii>stk;
	
	while(1)
	{
		if(v!=LCA)
		stk.push(mp(dfn[v],dfn[v]));
		if(st[v]==st[LCA])
		{
			if(v!=LCA&&fa[v]!=LCA)
			stk.push(mp(dfn[v]-1,dfn[LCA]+1));
			break;
			v=LCA;
		}
		else
		{
			if(v!=st[v])
			stk.push(mp(dfn[v]-1,dfn[st[v]]));
			v=fa[st[v]];
		}
	}
	while(stk.size())
	{
		swap(stk.top().fst,stk.top().sed);
		opt.pb(stk.top());
		stk.pop();
	}
	u=hu;v=hv;
	int ans=0;
	int pos=opt.size()-1;
	while(v&&dis(u,lst(v,pos))-a[u]>dis(u,hv)-dis(u,v)+w)
	{
		if(v==hv)sufmax[v]=val(v,pos)+dis(u,hv)-dis(u,v)+w;
		else sufmax[v]=max(sufmax[nxt(v,pos)],val(v,pos)+dis(u,hv)-dis(u,v)+w);
		get_last(v,pos);
	}
	deque<pii>d;
	int now=u,pn=1;
	int cnt=0;
	int kkk;
	while(1)
	{
		kkk=val(now,pn)+dis(u,lst(now,pn));
		while(d.size()&&val(d.back().fst,d.back().sed)+dis(u,lst(d.back().fst,d.back().sed))<=kkk)
		d.pop_back();
		d.push_back(mp(now,pn));
		if(now==v)break;
		get_next(now,pn);
		cnt++;
		if(cnt==L)
		{
			rep(i,pn,pos)
			{
				int nw;
				if(opt[i].fst==opt[i].sed)
				{
					nw=rev[opt[i].fst];
				}
				else
				{
					int l=opt[i].fst;
					int r=opt[i].sed;
					if(i==pn)l=dfn[now];
					if(i==pos)r=dfn[v];
					pii vl;
					if(l<r)
					{
						vl=query_upper(l,r);
						vl.fst+=dept[u]-dept[LCA]-dept[fa[LCA]];
					}
					else
					{
						vl=query_lower(r,l);
						vl.fst+=dept[u];
					}
					nw=vl.sed;
				}
				kkk=val(nw,i)+dis(u,lst(nw,i));
				while(d.size()&&val(d.back().fst,d.back().sed)+dis(u,lst(d.back().fst,d.back().sed))<=kkk)
				d.pop_back();
				d.push_back(mp(nw,i));
			}
			
			break;
		}
	}
	now=u,pn=1;
	while(1)
	{
		if(d.front().fst==now)d.pop_front();
		while(v!=hv&&dis(u,v)-dis(u,now)<=dis(u,lst(now,pn))+dis(u,hv)-dis(u,nxt(v,pos))+w)
		{
			get_next(v,pos);
			kkk=val(v,pos)+dis(u,lst(v,pos));
			while(d.size()&&val(d.back().fst,d.back().sed)+dis(u,lst(d.back().fst,d.back().sed))<=kkk)
			d.pop_back();
			d.push_back(mp(v,pos));
		}
		if(d.size())Max(ans,val(now,pn)+val(d.front().fst,d.front().sed)+dis(u,lst(d.front().fst,d.front().sed))-dis(u,now));
		if(v!=hv)Max(ans,sufmax[nxt(v,pos)]+val(now,pn)+dis(u,lst(now,pn)));
		else
		{
			get_next(now,pn);
			vl base=vl{0,0,0,0};

			rep(i,pn,pos)
			{
				if(opt[i].sed==opt[i].fst)
				{
					int kk=val(rev[opt[i].sed],i);
					base=base+vl{kk,kk,kk,a[rev[opt[i].sed]]};
				}
				else if(opt[i].fst<opt[i].sed)
				{
					if(pn==i)
					base=base+query(1,1,n,max(opt[i].fst,dfn[now]),opt[i].sed);
					else
					base=base+query(1,1,n,opt[i].fst,opt[i].sed);
				}
				else
				{
					vl g;
					if(pn==i)
					g=query(1,1,n,opt[i].sed,min(opt[i].fst,dfn[now]));
					else
					g=query(1,1,n,opt[i].sed,opt[i].fst);
					swap(g.premax,g.sufmax);
					base=base+g;
				}
			}
			Max(ans,base.maxn);
			break; 
		}
		if(now==hv)break;
		get_next(now,pn);
	}
	return ans;
}
void solve()
{
	init();
	cin>>n>>q>>L;
	rep(i,1,n)
	cin>>a[i];
	rep(i,2,n)
	{
		int u,v;
		cin>>u>>v;
		edge[u].pb(v);
		edge[v].pb(u);
	}
	dfs1(1,0);
	dfs2(1,0,1);
	dfs3(1,0);
	rep(i,1,n)
	{
		int u=rev[i];
		stmax[0][i]=0;
		if(suf[u].size())
		{
			Max(stmax[0][i],sufh[u][0]);
			Max(stmax[0][i],suf[u][0].fst+suf[u][0].sed+a[u]);
		}
		int vl=a[u];
		for(auto [w,from]:chain[u])
		{
			if(from==wson[u]||from==fa[u])continue;
			vl=w+a[u];
			break;
		}
		st_upper[0][i]=mp(vl+dept[fa[u]],u);
		st_lower[0][i]=mp(vl-dept[u],u);
	}
	rep(w,1,19)
	rep(i,1,n-(1<<w)+1)
	{
		stmax	[w][i]=max(	  stmax[w-1][i],   stmax[w-1][i+(1<<(w-1))]);
		st_upper[w][i]=max(st_upper[w-1][i],st_upper[w-1][i+(1<<(w-1))]);
		st_lower[w][i]=max(st_lower[w-1][i],st_lower[w-1][i+(1<<(w-1))]);
	}
	build(1,1,n);
	id++;
	while(q--)
	{
		int u,v,w;
		cin>>u>>v>>w;
		LCA=lca(u,v);
		fu=getson(u,LCA),fv=getson(v,LCA); 
		int val1=solve1(u,v,1);
		int val2=solve2(u,v,w);
		cout<<max(val1,val2)<<'\n';
	}
}
bool MT; 
signed main()
{
	freopen("path.in","r",stdin);
	freopen("path.out","w",stdout);
	int T=1;
	cin>>T;
	while(T--)
	solve();
	cerr<<"Memory:"<<(&MS-&MT)/1048576.0<<"MB Time:"<<clock()<<"ms\n";
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...