rt,Wa on #2 #8,用平衡树维护的dep和col的最大值,求hack或者找错,qwq
#include <bits/stdc++.h>
using namespace std;
namespace IO{
char buff[1<<21],*p1=buff,*p2=buff;
char getch(){return p1==p2&&(p2=((p1=buff)+fread(buff,1,1<<21,stdin)),p1==p2)?EOF:*p1++;}
template<typename T>
void read(T &x) {char ch=getch();int fl=1;x=0;while(ch>'9'||ch<'0'){if(ch=='-')fl=-1;ch=getch();}while(ch<='9'&&ch>='0') {x=x*10+ch-48;ch=getch();}x*=fl;}
template<typename T,typename ...Args>
void read(T &x,Args& ...args){read(x);read(args...);}
char obuf[1<<21],*p3=obuf;
void putch(char ch){if(p3-obuf<(1<<21))*p3++=ch;else fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=ch;}
char ch[100]; template<typename T>
void write(T x){if(!x)return putch('0');if(x<0)putch('-'),x*=-1;int top=0;while(x)ch[++top]=x%10+48,x/=10;while(top)putch(ch[top]),top--;}
template<typename T,typename ...Args>
void write(T x,Args ...args){write(x);write(args...);}
void flush(){fwrite(obuf,p3-obuf,1,stdout);}
}
using namespace IO;
int n,m,l,r,ans = -2e9;
int c[200005];
int siz[200005],son[200005],Size;
int rt,vis[200005];
int sum[200005],dis[200005];
int head[200005],tot;
struct s1mple{int d,s;} val[200005];
struct node{int nex,to,c;} edge[200005<<1];
inline void add(int x,int y,int c){edge[++tot].nex = head[x]; edge[tot].to = y; edge[tot].c = c; head[x] = tot;}
namespace elia//fhq压行了
{
int cnt,root,a,b,c,x,y,z;
struct fhq{int ls,rs,Dis,Col; int rnd,val,mx;} tr[20000005];
inline int New(int v,int Dis,int Col){++cnt; tr[cnt].val = tr[cnt].mx = v; tr[cnt].Col = Col; tr[cnt].Dis = Dis; tr[cnt].rnd = rand(); tr[cnt].ls = tr[cnt].rs = 0; return cnt;}
void update(int rt)
{
if (rt) tr[rt].mx = tr[rt].val;
if (tr[rt].ls) tr[rt].mx = max(tr[rt].mx,tr[tr[rt].ls].mx);
if (tr[rt].rs) tr[rt].mx = max(tr[rt].mx,tr[tr[rt].rs].mx);
}
void c_split(int rt,int val,int &x,int &y)//按颜色分裂
{
if (!rt){x = y = 0; return ;}
if (tr[rt].Col <= val){x = rt; c_split(tr[x].rs,val,tr[x].rs,y);}
else{y = rt; c_split(tr[y].ls,val,x,tr[y].ls);}
update(rt);
}
void d_split(int rt,int val,int &x,int &y)//按深度分裂
{
if (!rt){x = y = 0;return ;}
if (tr[rt].Dis <= val){x = rt; d_split(tr[x].rs,val,tr[x].rs,y);}
else{y = rt; d_split(tr[y].ls,val,x,tr[y].ls);}
update(rt);
}
int merge(int x,int y)
{
if (!x || !y) return x|y;
if (tr[x].rnd < tr[y].rnd){tr[x].rs = merge(tr[x].rs,y); update(x); return x;}
else{tr[y].ls = merge(x,tr[y].ls); update(y); return y;}
}
inline void insert(int v,int Dis,int Col)
{
c_split(root,Col,b,c); c_split(b,Col-1,a,b);
d_split(b,Dis,y,z); d_split(y,Dis-1,x,y);
if (!y) y = New(v,Dis,Col);
else tr[y].val = max(tr[y].val,v),tr[y].mx = tr[y].val;
b = merge(merge(x,y),z); root = merge(merge(a,b),c);
}
inline int same(int l,int r,int Col)//同色贡献
{
int res = -2e9;
c_split(root,Col,b,c); c_split(b,Col-1,a,b);
d_split(b,r,y,z); d_split(y,l-1,x,y);
if (y) res = tr[y].mx;
b = merge(merge(x,y),z); root = merge(merge(a,b),c);
return res;
}
inline int diff(int l,int r,int Col)//异色贡献
{
int res = -2e9;
c_split(root,Col-1,a,b); d_split(a,r,y,z); d_split(y,l-1,x,y);
if (y) res = tr[y].mx;
a = merge(merge(x,y),z); root = merge(a,b);
c_split(root,Col,a,b); d_split(b,r,y,z); d_split(y,l-1,x,y);
if (y) res = max(res,tr[y].mx);
b = merge(merge(x,y),z); root = merge(a,b);
return res;
}
inline pair<int,int> query(int l,int r,int Col){if(l>r)return make_pair(-2e9,-2e9); return make_pair(same(l,r,Col),diff(l,r,Col));}
}
void get_root(int x,int fa)
{
son[x] = 0; siz[x] = 1;
for (int i = head[x]; i; i = edge[i].nex)
{
int v = edge[i].to;
if (v == fa || vis[v]) continue;
get_root(v,x);
siz[x] += siz[v];
son[x] = max(son[x],siz[v]);
}
son[x] = max(son[x],Size-siz[x]);
if (son[x] < son[rt]) rt = x;
}
void get_dis(int x,int fa,int col)
{
++tot;
val[tot] = (s1mple){dis[x],sum[x]};
for (int i = head[x]; i; i = edge[i].nex)
{
int v = edge[i].to,cl = edge[i].c;
if (v == fa || vis[v]) continue;
dis[v] = dis[x]+1;
sum[v] = sum[x]+(col!=cl)*c[cl];
get_dis(v,x,cl);
}
}
void clac(int x)
{
elia::root = 0;
while (elia::cnt) elia::tr[elia::cnt--] = (elia::fhq){0,0,0,0,0,0,0};//清空
elia::tr[elia::cnt] = (elia::fhq){0,0,0,0,0,0,0};
for (int i = head[x]; i; i = edge[i].nex)
{
int v = edge[i].to,cl = edge[i].c;
if (vis[v]) continue;
dis[v] = 1; sum[v] = c[cl];
tot = 0;
get_dis(v,x,cl);
for (int i = 1; i <= tot; i++)
{
if (val[i].d > r) continue;
if (val[i].d >= l) ans = max(val[i].s,ans);
pair<int,int> res = elia::query(max(1,l-val[i].d),r-val[i].d,cl);
ans = max(ans,res.first+val[i].s-c[cl]);//同色
ans = max(ans,res.second+val[i].s);//异色
}
for (int i = 1; i <= tot; i++)
if (val[i].d < r) elia::insert(val[i].s,val[i].d,cl);
}
}
void solve(int x)
{
vis[x] = 1;
clac(x);
for (int i = head[x]; i; i = edge[i].nex)
{
int v = edge[i].to;
if (vis[v]) continue;
Size = siz[v]; rt = 0;
get_root(v,x);
solve(rt);
}
}
signed main()
{
read(n,m,l,r);
for (int i = 1; i <= m; i++)
read(c[i]);
for (int i = 1,u,v,c; i < n; i++)
read(u,v,c),add(u,v,c),add(v,u,c);
son[0] = Size = n;
get_root(1,0);
solve(rt);
write(ans);
flush();
return 0;
}