讲的题,但是没听而且感觉挺有意思而且见过类似的,于是自己做出来了。
首先有关键性质:若最大距离的同色点对为 ,树上的任意一条直径 满足 其中至少一个成立。
证明:反证。若有一条直径两端点为 且 不是任何的一个 或 , 互不相同,钦定 ,则 。同时,因为 为直径,,,于是 ,又 ,则 ,此时显然 同色且距离更远,不成立。
所以先找出任意一条直径 ,有 种情况同色,答案为 。否则,钦定 ,对于每个点 考虑钦定 的时,有多少种情况使得 与一个直径端点的距离是最终答案。
预处理出 然后排序后,处理出此时选这个点做答案的其中一个端点是否可行()有多少点 是 为 都行(即为排序后排名 ),然后计算即可。最后将这部分贡献 ,因为加上 的情况。
code:
int n,m,dis[N],g[N],h[N],pw[N],pos;
int tot,head[N];
struct node{
int to,nxt;
}e[N<<1];
il void add(int u,int v){
e[++tot]={v,head[u]},head[u]=tot;
}
il int Mod(int x,int y){
return x+y>=mod?x+y-mod:x+y;
}
void dfs(int u,int f){
if((dis[u]=dis[f]+1)>dis[pos]){
pos=u;
}
go(i,u){
int v=e[i].to;
if(v==f){
continue;
}
dfs(v,u);
}
}
void getDis(int u,int f,int *d){
go(i,u){
int v=e[i].to;
if(v==f){
continue;
}
d[v]=d[u]+1,getDis(v,u,d);
}
}
void Yorushika(){
scanf("%d",&n);
rep(i,1,n-1){
int u,v;scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
int u,v;
dfs(1,0),u=pos,pos=0;
dfs(u,0),v=pos;
getDis(u,0,g),getDis(v,0,h);
pw[0]=1;
rep(i,1,n){
pw[i]=2*pw[i-1]%mod;
}
int ans=1ll*pw[n-1]*g[v]%mod;
rep(i,1,n){
if(g[i]>h[i]){
swap(g[i],h[i]);
}
}
sort(g+1,g+n+1),sort(h+1,h+n+1);
rep(i,1,n-2){
if(g[n]>h[i]){
continue;
}
ans=Mod(ans,2ll*h[i]*pw[i-1]%mod);
}
int p=lower_bound(h+1,h+n-1,g[n])-h-1;
ans=Mod(ans,2ll*g[n]*pw[p]%mod);
printf("%d\n",ans);
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}