专栏文章
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 条评论,欢迎与作者交流。
正在加载评论...