代码求调:第2,10个点TLE
#include<iostream>
#include<climits>
#include<algorithm>
#define int long long
using namespace std;
inline int read(){register int x = 0, f = 1;register char c = getchar();while (c < '0' || c > '9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return x * f;}
inline void write(int x){if (x < 0) putchar('-'), x = -x;if (x > 9) write(x / 10);putchar(x % 10 + '0');}
const int N = 2e5 + 10;
int n, m, L, R, rt, ans = INT_MIN;
int c[N];
int t1[N << 2], t2[N << 2];
void pushup(int now, int t[]){
t[now] = max(t[now << 1], t[now << 1 | 1]);
}
void build(int now, int l, int r, int t[]){
if (l == r){
t[now] = LLONG_MIN;
return;
}
int mid = (l + r) >> 1;
build(now << 1, l, mid, t);
build(now << 1 | 1, mid + 1, r, t);
pushup(now, t);
}
void modify(int now, int l, int r, int x, int k, int t[]){
if (l == r){
if (k == LLONG_MIN) t[now] = k;
else t[now] = max(t[now], k);
return;
}
int mid = (l + r) >> 1;
if (x <= mid) modify(now << 1, l, mid, x, k, t);
else modify(now << 1 | 1, mid + 1, r, x, k, t);
pushup(now, t);
}
int query(int now, int l, int r, int x, int y, int t[]){
if (x <= l && r <= y) return t[now];
int mid = (l + r) >> 1, res = LLONG_MIN;
if (x <= mid) res = max(res, query(now << 1, l, mid, x, y, t));
if (mid + 1 <= y) res = max(res, query(now << 1 | 1, mid + 1, r, x, y, t));
return res;
}
struct edge{
int v, w, col, nxt;
}e[N << 1];
int head[N], cnt;
void add(int u, int v, int w, int col){
e[++cnt] = (edge){v, w, col, head[u]};
head[u] = cnt;
}
struct node{
int dis, l, c, id;
bool operator < (const node &b) const{
if (c != b.c) return c < b.c;
return id < b.id;
}
}stk[N];
int sz[N], mx[N], maxn, top, dis[N], l[N];
bool vis[N];
void find(int u, int fa){
sz[u] = 1, mx[u] = 0;
for (int i = head[u]; i; i = e[i].nxt){
int v = e[i].v;
if (v == fa || vis[v]) continue;
find(v, u);
sz[u] += sz[v];
mx[u] = max(mx[u], sz[v]);
}
mx[u] = max(mx[u], maxn - sz[u]);
if (mx[u] < mx[rt]) rt = u;
}
void dfs(int u, int fa, int col, int last, int id){
stk[++top] = (node){dis[u], l[u], col, id};
for (int i = head[u]; i; i = e[i].nxt){
int v = e[i].v;
if (v == fa || vis[v]) continue;
if (e[i].col != last) dis[v] = dis[u] + e[i].w;
else dis[v] = dis[u];
l[v] = l[u] + 1;
dfs(v, u, col, e[i].col, id);
}
}
void calc(int u){
top = 0;
int id = 0;
for (int i = head[u]; i; i = e[i].nxt){
int v = e[i].v;
if (vis[v]) continue;
dis[v] = e[i].w, l[v] = 1;
dfs(v, u, e[i].col, e[i].col, ++id);
}
sort(stk + 1, stk + top + 1);
build(1, 1, top + 1, t1);
build(1, 1, top + 1, t2);
modify(1, 1, top + 1, 1, 0, t2);
int l = 1, r = 1;
for (int i = 1; i <= top; i++){
if (stk[i].id != stk[i - 1].id && i != 1){
if (stk[i].c == stk[i - 1].c){
for (int j = l; j <= r; j++) modify(1, 1, top + 1, stk[j].l + 1, stk[j].dis, t1);
}else{
for (int j = l; j <= r; j++) modify(1, 1, top + 1, stk[j].l + 1, LLONG_MIN, t1), modify(1, 1, top + 1, stk[j].l + 1, stk[j].dis, t2);
l = r = i;
}
}else r = i;
int x = query(1, 1, top + 1, max(min(L - stk[i].l, top) + 1, 1ll), max(min(R - stk[i].l, top) + 1, 1ll) + 1, t1);
int y = query(1, 1, top + 1, max(min(L - stk[i].l, top) + 1, 1ll), max(min(R - stk[i].l, top) + 1, 1ll), t2);
if (x != LLONG_MIN) ans = max(ans, x - c[stk[i].c] + stk[i].dis);
if (y != LLONG_MIN) ans = max(ans, y + stk[i].dis);
}
}
void solve(int u){
vis[u] = 1;
calc(u);
for (int i = head[u]; i; i = e[i].nxt){
int v = e[i].v;
if (vis[v]) continue;
rt = 0;
maxn = sz[v];
find(v, 0);
solve(rt);
}
}
signed main(){
n = read(), m = read(), L = read(), R = read();
for (int i = 1; i <= m; i++) c[i] = read();
for (int i = 1; i < n; i++){
int u = read(), v = read(), col = read(), w = c[col];
add(u, v, w, col), add(v, u, w, col);
}
maxn = mx[rt] = n;
find(1, 0);
solve(rt);
cout << ans;
return 0;
}