2023NOIP A层联测32 T3 sakuya
2023NOIP A层联测32 T3 sakuya
虚伪的期望,彬彬赛时都能 A 的数学题。
思路
考虑算出来总的花费,再除以
对于某个排列的花费为:
但考虑一下,这个式子重要吗?
我们的目的是求出所有排列的花费的和,不能局限于某一个排列去求。
其实,如果我们知道每一种相邻两个数出现的次数,乘上这两个点间的距离,也可以算出答案。
那么我们考虑
赛时通过打表得知,
先在这
将
所以说,对于一对数
也就是说,每一个
答案为:
化简为:
现在求出
先没有修改操作,这个式子可以统计一条边两边的有效点(在集合
如果加上修改,那么每次会影响到和这个点相连的边,但我们不可以遍历这个点的所有边重新算贡献,这样菊花图会 TLE。
所以考虑将与一个点相连的边经过的总次数存在点上,修改时直接将总次数乘以
时间复杂度
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 998244353
const int maxn=5e5+5;
struct node
{
int to,nxt;
ll w;
}edge[maxn*2];
int n,tot,m;
int head[maxn];
ll ans,inv;
ll sz[maxn],c[maxn],fac[maxn];
ll ksm(ll x,ll y)
{
ll sum=1;
for(;y;y/=2,x=x*x%mod) if(y&1) sum=sum*x%mod;
return sum;
}
void add(int x,int y,int z)
{
tot++;
edge[tot].to=y;
edge[tot].nxt=head[x];
edge[tot].w=z;
head[x]=tot;
}
void dfs(int u,int f)
{
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==f) continue;
dfs(v,u);
sz[u]+=sz[v];
}
}
void dfs_ans(int u,int f)
{
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==f) continue;
ans=(ans+sz[v]*(sz[1]-sz[v])%mod*edge[i].w)%mod;
dfs_ans(v,u);
}
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v!=f) c[u]=(c[u]+sz[v]*(sz[1]-sz[v])%mod)%mod;
else c[u]=(c[u]+sz[u]*(sz[1]-sz[u])%mod)%mod;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
sz[x]=1;
}
dfs(1,0);
dfs_ans(1,0);
fac[0]=1;
for(int i=1;i<=m;i++) fac[i]=fac[i-1]*i%mod;
inv=ksm(fac[m],mod-2);
int _;
scanf("%d",&_);
while(_--)
{
int x;
ll k;
scanf("%d%lld",&x,&k);
ans=(ans+c[x]*k)%mod;
printf("%lld\n",ans*inv%mod*2*fac[m-1]%mod);
}
}
第一次赛时切期望( ̄▽ ̄)~*
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构