题面
对于每个重心,每个子树可以求出一个数组,表示每个深度的答案。先同种颜色合并,再不同颜色合并。合并可以按高度从小到大排序,然后跑单调队列,复杂度$O(n\log n)$。我比较脑抽,写的是从大到小排序,然后跑线段树,复杂度$O(n\log^2 n)$。
#include
#define pb push_back
#define RAN(v)v.begin(),v.end()
#define FOR(i,v)\
for(typeof(v.end())i=v.begin();i!=v.end();++i)
#define I (J+1)
#define J (i+j>>1)
#define P (k<<1)
#define S (P^1)
using namespace std;
const int inf=2e9;
struct buf{
operator int(){
int x=0,y=0,c=getchar();
while(c<48)
y=c==45,c=getchar();
while(c>47)
x=x*10+c-48,c=getchar();
return y?-x:x;
}
}it;
const int N=2e5+5;
struct info{int v,c;};
vectore[N];
int ans=-inf;
int n,m,l,r,siz[N],w[N];
bool vis[N];
int len,f[N*4];
void pre(vector&v,int i,int j,int k){
if(i==j)f[k]=v[i-1];
else{
pre(v,i,J,P),pre(v,I,j,S);
f[k]=max(f[P],f[S]);
}
}
void pre(vector&v){
len=v.size();
pre(v,1,len,1);
}
void cov(int u,int v,int i,int j,int k){
if(i==j)f[k]=max(f[k],v);
else{
uJ?ask(u,v,I,j,S):max(ask(u,J,i,J,P),ask(I,v,I,j,S));
}
int ask(int u,int v){
u=max(u,1);
v=min(v,len);
return u>v?-inf:ask(u,v,1,len,1);
}
bool cmp(const vector&a,const vector&b){
return a.size()>b.size();
}
void dfs1(int u,int p){
siz[u]=1;
FOR(i,e[u])
if(i->v!=p&&!vis[i->v])
dfs1(i->v,u),siz[u]+=siz[i->v];
}
int dfs2(int u,int p,int n){
int s=n-siz[u];
FOR(i,e[u])
if(i->v!=p&&!vis[i->v]){
if(int c=dfs2(i->v,u,n))return c;
s=max(s,siz[i->v]);
}
return s*2<=n?u:0;
}
int dfs4(int u,int p,int d){
int s=d;
if(dv!=p&&!vis[i->v])
s=max(s,dfs4(i->v,u,d+1));
return s;
}
vectorcur;
void dfs5(int u,int p,int c,int d,int s){
cur[d]=max(cur[d],s);
if(dv!=p&&!vis[i->v])
dfs5(i->v,u,i->c,d+1,c!=i->c?s+w[i->c]:s);
}
void dfs3(int u){
dfs1(u,0);
if(siz[u]>l){
u=dfs2(u,0,siz[u]);
vis[u]=1;
map > >col;
FOR(i,e[u])
if(!vis[i->v]){
int n=dfs4(i->v,0,1);
cur.assign(n,-inf);
dfs5(i->v,0,i->c,0,w[i->c]);
col[i->c].pb(cur);
}
vector >tmp;
FOR(i,col){
sort(RAN(i->second),cmp);
vector&s=i->second.front();
pre(s);
FOR(j,i->second)
if(j!=i->second.begin()){
vector&v=*j;
if(v.size()+len>=l)
for(int k=0;kfirst]);
}
for(int k=0;k1){
sort(RAN(tmp),cmp);
pre(tmp.front());
FOR(i,tmp)
if(i!=tmp.begin()){
vector&v=*i;
if(v.size()+len>=l)
for(int j=0;jv])dfs3(i->v);
}
}
int main(){
n=it,m=it,l=it,r=it;
for(int i=1;i<=m;++i)
w[i]=it;
for(int i=2;i<=n;++i){
int u=it,v=it,c=it;
e[u].pb({v,c});
e[v].pb({u,c});
}
dfs3(1);
printf("%d\n",ans);
}