Solución: CF 1401 D \ mathrm {CF1401D}C F 1 4 0 1 D
Significado del tema
S ol \ mathrm {Sol} S o l
Codicioso en el árbol simple
Debemos considerar el peso de una arista vi v_ivyoLs ls a la izquierdal s apunta a la derecha(n - ls) (n-ls)( n-l s ) puntos, entonces la contribución de este borde esls (n - ls) × vi ls (n-ls) \ times v_ila s ( n-l s )×vyo
Luego, debemos hacer todo lo posible para maximizar la contribución de los pesos grandes y agregarlos en orden de mayor a menor, y el resto es una simple simulación.
Complejidad del tiempo: O (n log n) O (n \ log n)O ( nlo gn )
C ode \ mathrm {Código} C o d e
const int N=2e5+5;
int n,m,siz[N],head[N],cnt,P[N],S[N],bo[N],cwy,ans;
struct Node
{
int nex,to;
};
Node e[N<<1];
inline void jia(int u,int v)
{
e[++cnt].nex=head[u];
head[u]=cnt;
e[cnt].to=v;
}
inline void dfs(int u,int fa)
{
siz[u]=1;
GO(i,u)
{
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
siz[u]+=siz[v];
S[++cwy]=siz[v]*(n-siz[v]);//记录每条边的贡献
}
}
inline bool Cmp(int x,int y) {
return x>y; }
inline void Add(int &x,int y) {
x+=y; if(x>=mod) x-=mod; }
signed main()
{
int Q;
io.read(Q);
for (;Q--;)
{
io.read(n);
For(i,1,n) head[i]=0,siz[i]=0;
cwy=cnt=ans=0;
For(i,1,n-1)
{
int x,y;
io.read(x),io.read(y);
jia(x,y);
jia(y,x);
}
io.read(m);
For(i,1,m) io.read(P[i]);
dfs(1,0);
sort(P+1,P+m+1,Cmp);
sort(S+1,S+cwy+1,Cmp);//分别从大到小排序
if(m<n)
{
For(i,m+1,n) P[i]=1;//不足n-1条边就用1补齐
For(i,1,n-1) Add(ans,P[i]*S[i]%mod);
io.write((ans+mod)%mod);
puts("");
}
else
{
int st=m-n+2;
int tot=1ll;
For(i,1,st) tot=tot*P[i]%mod;
ans=tot*S[1]%mod;
//否则把前面几个大的合并记录贡献
For(i,2,n-1) Add(ans,P[st+i-1]*S[i]%mod);
io.write((ans+mod)%mod);
puts("");
}
}
return 0;
}