8月13日模拟赛
T1 \(Sign\)
题目
这是一道签到题
给出一棵\(N\)个节点的树,求所有七点为叶节点的有向路径,其上每一条边权值和的和
\(Input\)
第一行是一个整数\(N\)。
接下来\(N-1\)行,每行三个整数\(L_i,A_i,B_i\),代表存在一条
连接\(A_i\)和\(B_i\)的长度为\(L_i\)的边。
\(Output\)
输出一个整数,代表所求结果
题解
对于一个以\(x\)为根的树,用\(dfs\)序找到他的 子树大小(\(size\))和叶子节点个数(\(s\)),计算每条边的贡献。
如果是子树中的叶子节点向外走,贡献为:
\(s_x*(n-size_x)*dis\)
如果是子树外的叶子节点向里走,贡献为:
\((sum-s_x)*size_x*dis\)
其中,\(sum\)是总叶子节点个数
\(code\):
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+105;
int n,siz[N],sum,root,s[N],cnt,h[N<<1],de[N],tot,x,y,z,ans;
struct edge{int nex,to,v;}e[N<<1];
struct edge2{int fr,t,d;}a[N];
inline void add(int x,int y,int z){
e[++cnt].to=y;e[cnt].v=z;
e[cnt].nex=h[x];h[x]=cnt;
}
void dfs(int x,int f){
siz[x]=1;
if(de[x]==1) s[x]=1;
for(int i=h[x];i;i=e[i].nex){
int y=e[i].to;if(y==f) continue;
a[++tot].fr=x;a[tot].t=y;a[tot].d=e[i].v;
dfs(y,x);
siz[x]+=siz[y];s[x]+=s[y];
}
}
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
signed main(){
n=read();
for(int i=1;i<n;i++){x=read();y=read();z=read();add(y,z,x);add(z,y,x);de[z]++;de[y]++;}
for(int i=1;i<=n;i++)if(de[i]>1)root=i;else sum++;
dfs(root,0);
for(int i=1;i<n;i++){
int k1=s[a[i].t]*(n-siz[a[i].t])*a[i].d;
int k2=siz[a[i].t]*(sum-s[a[i].t])*a[i].d;
ans+=k1+k2;
}
printf("%lld",ans);
return 0;
}
T2 \(Map\)
题目
一张\(N\)个点的无向完全图,从\(1\)号点出发,每秒随机沿当前点的出度移动一条边。\(Q\)次询问,每次给出一个数\(t_i\),询问第\(t_i\)秒在\(1\)号点的概率,答案对\(998244353\)取模。
\(Input\)
第一行是两个整数\(N,Q\)。
接下来\(Q\)行,每行一个整数,第\(i+1\)行的数字代表\(t_i\)。
\(Output\)
输出\(Q\)行,每行一个非负整数,第\(i\)行的数字代表第\(i\)次询问的结果。
样例
\(Input\)
\(3\) \(2\)
\(0\)
\(2\)
\(Output\)
\(1\)
\(499122177\)
T3
见此处
T4
座右铭:我从来没有见过这样阴郁而又光明的日子。