rt
已经调了了一个下午 + 一个晚上了
救救孩子
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rint register int
#define fill(x,y) memset(x,y,sizeof(x))
#define copy(x,y) memcpy(y,x,sizeof(x))
#define _File
using namespace std;
inline int read(){
int w=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){w=(w<<3)+(w<<1)+(ch^48); ch=getchar();}
return w*f;
}
const int maxn=2e5+5,inf=0x3f3f3f3f;
int n,m,L,R;
int col[maxn];//边存的是颜色种类,col存的是权值
namespace Graph{
int head[maxn],id;
struct e{
int v,w,next;
}edge[maxn<<1];
inline void add(int u,int v,int w){
edge[++id].v=v;
edge[id].w=w;
edge[id].next=head[u];
head[u]=id;
}
}using namespace Graph;
namespace SegmentTree{
int rt1,rt2,tot;//1 not same;2 same
struct node{
int lson,rson,maxx;
#define lson(x) t[x].lson
#define rson(x) t[x].rson
#define maxx(x) t[x].maxx
node(){lson=rson=0; maxx=-inf;}
inline void init(){lson=rson=0; maxx=-inf;}
}t[maxn<<5];
inline void pushup(int p){
maxx(p)=max(maxx(lson(p)),maxx(rson(p)));
}
inline void del(int &p){t[p].init(); p=0;}
inline void clear(){
for(int i=1;i<=tot;i++) t[i].init();
rt1=rt2=tot=0;
}
void update(int &p,int l,int r,int pos,int k){
if(!p) p=++tot,t[p].init();
if(l==r) return maxx(p)=max(maxx(p),k),void();
int mid=(l+r)>>1;
if(pos<=mid) update(lson(p),l,mid,pos,k);
else update(rson(p),mid+1,r,pos,k);
pushup(p);
}
int query(int p,int l,int r,int tl,int tr){
if(!p) return -inf;
if(tl<=l && r<=tr) return maxx(p);
int mid=(l+r)>>1,res=-inf;
if(tl<=mid) res=max(res,query(lson(p),l,mid,tl,tr));
if(tr>mid) res=max(res,query(rson(p),mid+1,r,tl,tr));
return res;
}
int merge(int x,int y,int l,int r){
if(!x || !y) return x+y;
if(l==r){
maxx(x)=max(maxx(x),maxx(y));
del(y); return x;
}
int mid=(l+r)>>1;
lson(x)=merge(lson(x),lson(y),l,mid);
rson(x)=merge(rson(x),rson(y),mid+1,r);
del(y); pushup(x); return x;
}
}using namespace SegmentTree;
namespace PointDivide{
int root,S,top,ans=-inf;
int size[maxn],wt[maxn];
bool vis[maxn];
struct node{int val,dep;}stk[maxn];
void findroot(int u,int fa){
size[u]=1; wt[u]=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(v==fa || vis[v]) continue;
findroot(v,u);
size[u]+=size[v];
wt[u]=max(wt[u],size[v]);
}
wt[u]=max(wt[u],S-size[u]);
if(wt[u]<wt[root]) root=u;
}
void dfs(int u,int fa,int val,int dep,int lstcol){
if(dep>R) return;
stk[++top]=(node){val,dep};
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v,w=edge[i].w;
if(v==fa || vis[v]) continue;
dfs(v,u,(w==lstcol)?val:val+col[w],dep+1,w);
}
}
void calc(int u){
SegmentTree::clear();
int lstcol=0,flag=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v,w=edge[i].w;
if(vis[v]) continue;
top=flag=0;
dfs(v,u,col[w],1,w);
if(w==lstcol) flag=1;
else rt1=merge(rt1,rt2,1,n),rt2=0;
for(int j=1;j<=top;j++){
if(flag) ans=max(ans,query(rt2,1,n,max(1,L-stk[j].dep),R-stk[j].dep)+stk[j].val-col[lstcol]);
ans=max(ans,query(rt1,1,n,max(1,L-stk[j].dep),R-stk[j].dep)+stk[j].val);
if(stk[j].dep>=L && stk[j].dep<=R) ans=max(ans,stk[j].val);
}
for(int j=1;j<=top;j++) update(rt2,1,n,stk[j].dep,stk[j].val);
lstcol=w;
}
}
void solve(int u){
vis[u]=1; calc(u);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(vis[v]) continue;
S=size[v]; wt[root=0]=inf;
findroot(v,0); solve(root);
}
}
}using namespace PointDivide;
int main(){
#ifdef _File
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
n=read(); m=read(); L=read(); R=read();
for(int i=1;i<=m;i++) col[i]=read();
for(int i=1;i<n;i++){
int x=read(),y=read(),z=read();
add(x,y,z); add(y,x,z);
}
S=wt[root=0]=n;
findroot(1,0); solve(root);
printf("%d\n",ans);
return 0;
}