永琳的竹林迷径(path)

题目描述

竹林可以看作是一个n 个点的树,每个边有一个边长wi,其中有k 个关键点,永琳需要破坏这些关键点才能走出竹林迷径。

然而永琳打算将这k 个点编号记录下来,然后随机排列,按这个随机的顺序走过k 个点,但是两点之间她只走最短路线。初始时永琳会施展一次魔法,将自己传送到选定的k 个点中随机后的第一个点。

现在永琳想知道,她走过路程的期望是多少,答案对998244353 取模。

注意,如果对期望不理解,题目最后有详细解释,请自行阅读。

输入

第一行一个数Case,表示测试点编号。(样例的编号表示其满足第Case 个测试点的性质)

下一行一个n,表示树的点数。

下面 n-1 行,每行三个数ui,vi,wi,表示一条边连接ui和vi,长度为wi。

下面一行一个数k,表示关键点数。

下面一行k 个数,表示k 个关键点的编号。

输出

一行一个数,表示答案(对998244353 取模)。

数据范围

对于 100%的数据,保证1≤wi≤1041≤wi≤104。

测试点编号

n

k

特殊性质

1

≤10≤10

=1=1

2

3

≤5≤5

4

5

≤1000≤1000

≤7≤7

6

7

≤105≤105

≤8≤8

8

9

10

≤16≤16

11

12

13

≤105≤105

14

15

16

17

18

≤106≤106

≤106≤106

是一条链

19

20

21

22

23

24

25

【可能会用到的知识】

关于期望:

期望的定义:离散随机变量的一切可能值与其对应的概率P 的乘积之和称为数学期望。

即: E(x)=∑P(x=k)×val(k)E(x)=∑P(x=k)×val(k)

其中E(x)是期望,P(x=k)是 x=k 发生的概率。

提示:答案必定可以表示成pqpq的形式,在模意义下,pq=p×q−1pq=p×q−1,其中q−1q−1是qq的逆元。

【提示】

读入数据较大,请使用快速的读入方式。


solution

本题求有序走完一个排列的期望长度。

考虑一个点i之前是j的贡献:dist[i]+dist[j]-2*dist[lca]

算出所有点的dist的贡献,lca的贡献则做一次类似树形dp的东西

一个点不同子树互相走的数量就是它作lca的贡献

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 1000006
#define mod 998244353
#define ll long long
using namespace std;
int n,num,head[maxn],s[maxn],flag[maxn],t1,t2,t3,tot;
int Te,size[maxn];
ll ans,Sum,ny2,ny,d[maxn];
struct node{
int v,nex,w;
}e[maxn*2];
int read(){
int v=0,ch;
while(!isdigit(ch=getchar()));v=ch-48;
while(isdigit(ch=getchar()))v=(v<<1)+(v<<3)+ch-48;
return v;
}
void lj(int t1,int t2,int t3){
e[++tot].v=t2;e[tot].w=t3;e[tot].nex=head[t1];head[t1]=tot;
}
void dfs(int k,int fa,ll dist){ d[k]=dist;
for(int i=head[k];i;i=e[i].nex){
if(e[i].v==fa)continue;
dfs(e[i].v,k,dist+e[i].w);
size[k]+=size[e[i].v];
}
size[k]+=flag[k];
}
void dp(int k,int fa){
ll sum=0;
for(int i=head[k];i;i=e[i].nex){
if(e[i].v==fa)continue;
dp(e[i].v,k);
sum+=size[e[i].v];
}
ll cnt=0;
for(int i=head[k];i;i=e[i].nex){
if(e[i].v==fa)continue;
cnt=cnt+size[e[i].v]*(sum-size[e[i].v])%mod;
cnt=cnt%mod;
}
ans=(ans-2*d[k]%mod*cnt%mod)%mod;
if(flag[k]){
ans=(ans-4*d[k]%mod*sum%mod)%mod;
}
}
ll work(ll a,int Num){
ll Ans=1,p=a;
while(Num){
if(Num&1)Ans=Ans*p;
p=p*p;p%=mod;Ans%=mod;Num>>=1;
}
return Ans;
}
int main()
{
Te=read();n=read();
for(int i=1;i<n;i++){
t1=read();t2=read();t3=read();
lj(t1,t2,t3);lj(t2,t1,t3);
}
num=read();
for(int i=1;i<=num;i++){
s[i]=read();flag[s[i]]++;
}
dfs(1,0,(ll)0);
ny2=work(2,mod-2);
for(int i=1;i<=num;i++)Sum+=d[s[i]];
for(int i=1;i<=num;i++){
ans=(ans+d[s[i]]*(num-1))%mod+(Sum-d[s[i]])%mod;
ans=ans%mod;
}
dp(1,0);ans%=mod;
ans=ans*work(num,mod-2);
ans=(ans%mod+mod)%mod;
printf("%lld\n",ans);
return 0;
}

永琳的竹林迷径(path)的更多相关文章

  1. Attention Points

    Attention Points 数组范围 无向图.树,边表的范围是边数的两倍. 因为最近树的题目做的比较多,一定要注意分清是树还是图,不能冲上去就去开struct Edge{int to,ne,w; ...

  2. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  3. 1、C#基础:变量、运算符、分支、循环、枚举、数组、方法 <转>

    转自:海盗船长 链接:http://www.cnblogs.com/baidawei/p/4701504.html#3241882 C#..Net以及IDE简介 一.什么是.Net? .Net指 .N ...

  4. Android 吸入动画效果详解

    1,背景 吸入(Inhale)效果,最初我是在iOS上面看到的,它是在Note程序中,用户可能添加了一页记录,在做删除时,它的删除效果是:这一页内容吸入到一个垃圾框的图标里面.请看下图所示: ==== ...

  5. Windows驱动开发入门指引

       1.  前言 因工作上项目的需要,笔者需要做驱动相关的开发,之前并没有接触过相关的知识,折腾一段时间下来,功能如需实现了,也积累了一些经验和看法,所以在此做番总结. 对于驱动开发的开发指引,微软 ...

  6. 教老婆学Linux运维(二)Linux常用命令指南【上】

    目录 教老婆学Linux(二)Linux常用命令指南[上] 一.概述 二.常用命令 教老婆学Linux(二)Linux常用命令指南[上] 作者:姚毛毛的博客 tips:文章太长,分两篇发出,本篇发前三 ...

  7. SpringCloud:学习Gateway网关拦截器的ServerWebExchange

    1.Gateway的拦截器 我们要在项目中实现一个拦截器,需要继承两个类:GlobalFilter, Ordered GlobalFilter:全局过滤拦截器,在gateway中已经有部分实现,具体参 ...

  8. 模拟退火解TSP问题MATLAB代码

    分别把前四个函数存成m文件,再运行最后一个. swap.m function [ newpath , position ] = swap( oldpath , number ) % 对 oldpath ...

  9. EOS主网搭建教程--&&--搭建节点--&&--搭建mongodb数据库

    EOS主网搭建教程: 1.git clone https://github.com/EOS-Mainnet/eos.git --recursive 2.cd eos 3.git tag (查看有哪些分 ...

随机推荐

  1. daemon函数实现原理 守护进程

    linux提供了daemon函数用于创建守护进程,实现原理如下: #include <unistd.h> int daemon(int nochdir, int noclose); 1.  ...

  2. vue学习之路 - 2.基本操作(上)

    基本操作(上) 本章节简介: vue的安装 vue实例创建 数据绑定渲染 表单数据双向绑定 事件处理 安装 安装方式有三种: 一.vue官网直接下载 http://vuejs.org/js/vue.m ...

  3. 牛客NOIP提高组R1 A中位数(二分)

    题意 题目链接 Sol 很神仙的题目啊,考场上只会$n^2$的暴力.. 考虑直接二分一个$mid$,我们来判断最终答案是否可能大于$x$. 判断的时候记录一下前缀最小值即可, 设$s[i]$表示$1- ...

  4. EasyUI获取正在编辑状态行的索引

    function getRowIndex(target){ var tr = $(target).closest("tr.datagrid-row"); return paseIn ...

  5. pm2 服务器命令

    1..配置日志文件路径 命令:pm2 start /home/admin/node/fotonIp/bin/www  --name ip -i 4  -o   "/app/node/logs ...

  6. mysql 5.7安装步骤:

    .下载完成后解压: 3.在mysql要目录下创建 my.ini 文件,如上图,文件内容如下,basedir 和 datadir 修改为相应地址: [mysql] # 设置mysql客户端默认字符集 d ...

  7. crontab -e 和/etc/crontab的区别

    /etc/crontab文件和crontab -e命令区别/etc/crontab文件和crontab -e命令区别 1.格式不同 前者 # For details see man 4 crontab ...

  8. 【PHP】详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI、SCRIPT_NAME、PHP_SELF区别

    实例:1.http://localhost/index.php/Home/Home/index.html $_SERVER['QUERY_STRING'] = ""; $_SERV ...

  9. MySQL批量插入大量数据方法

    在MySQL数据库中,如果要插入上百万级的记录,用普通的insert into来操作非常不现实,速度慢人力成本高,推荐使用Load Data或存储过程来导入数据,我总结了一些方法分享如下,主要基于My ...

  10. Git add命令

    git add -A和 git add .   git add -u在功能上看似很相近,但还是存在一点差别 git add . :他会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文 ...