打卡信奥刷题(3356)用C++实现信奥题 P9584 「MXOI Round 1」城市
P9584 「MXOI Round 1」城市
题目描述
小 C 是 F 国的总统,尽管这个国家仅存在于网络游戏中,但他确实是这个国家的总统。
F 国由 nnn 个城市构成,这 nnn 个城市之间由 n−1n-1n−1 条双向道路互相连接。保证从任意一个城市出发,都能通过这 n−1n-1n−1 条双向道路,到达任意一个城市。
当然,通过这些双向道路是要收费的。通过第 iii 条双向道路,需要花费 cic_ici 元。我们称 cic_ici 为第 iii 条双向道路的费用。
我们定义 cost(x,y)cost(x,y)cost(x,y) 表示从城市 xxx 到城市 yyy 的简单路径上,所有经过的双向道路的费用之和。特殊地,当 x=yx=yx=y 时,cost(x,y)=0cost(x,y)=0cost(x,y)=0。
为了促进 F 国发展,小 C 新建了一个城市 n+1n+1n+1。现在他需要再新建一条双向道路,使得城市 n+1n+1n+1 也可以通过这 nnn 条双向道路到达任意一个城市。
他共有 qqq 个新建道路的方案,每个方案会给定两个参数 ki,wik_i,w_iki,wi;对于每一个方案,你需要求出在新建一条连接城市 kik_iki 和城市 n+1n+1n+1 且费用为 wiw_iwi 的双向道路后,所有 cost(i,j)cost(i,j)cost(i,j) 之和,即 ∑i=1n+1∑j=1n+1cost(i,j)\sum\limits_{i=1}^{n+1} \sum\limits_{j=1}^{n+1} cost(i,j)i=1∑n+1j=1∑n+1cost(i,j)。
由于答案可能很大,所以你只需要输出答案对 998244353998244353998244353 取模的结果。
方案之间相互独立,也就是说所有方案不会影响现有的道路,这些方案不会真正被施行。
输入格式
第一行两个整数 n,qn,qn,q。
接下来 n−1n-1n−1 行,第 iii 行三个整数 ui,vi,ciu_i,v_i,c_iui,vi,ci,表示存在一条连接城市 uiu_iui 和城市 viv_ivi 的双向道路,其费用为 cic_ici。
接下来 qqq 行,第 iii 行两个整数 ki,wik_i,w_iki,wi,表示一个新建道路的方案。
输出格式
共 qqq 行,每行一个整数,第 iii 行的整数表示在新建一条连接城市 kik_iki 和城市 n+1n+1n+1 且费用为 wiw_iwi 的双向道路后,所有 cost(i,j)cost(i,j)cost(i,j) 之和对 998244353998244353998244353 取模的结果,即 ∑i=1n+1∑j=1n+1cost(i,j) mod 998244353\sum\limits_{i=1}^{n+1} \sum\limits_{j=1}^{n+1} cost(i,j) \bmod 998244353i=1∑n+1j=1∑n+1cost(i,j)mod998244353。
输入输出样例 #1
输入 #1
4 2
2 1 3
3 2 2
4 2 4
1 2
2 2
输出 #1
100
88
输入输出样例 #2
输入 #2
9 5
2 3 6
6 1 4
5 2 10
2 4 1
9 1 9
2 8 3
1 2 3
7 4 8
4 9
7 3
6 1
9 7
2 1
输出 #2
1050
1054
970
1148
896
说明/提示
【样例解释 #1】
在新建一条连接城市 111 和城市 555 且费用为 222 的双向道路后,F 国的道路如下图所示:

例如,此时 cost(4,5)=9cost(4,5)=9cost(4,5)=9,cost(1,3)=5cost(1,3)=5cost(1,3)=5。
容易求得此时 ∑i=1n+1∑j=1n+1cost(i,j)=100\sum\limits_{i=1}^{n+1} \sum\limits_{j=1}^{n+1} cost(i,j)=100i=1∑n+1j=1∑n+1cost(i,j)=100。
【样例 #3】
见附加文件中的 city/city3.in 与 city/city3.ans。
该样例满足测试点 444 的限制。
【样例 #4】
见附加文件中的 city/city4.in 与 city/city4.ans。
该样例满足测试点 111111 的限制。
【样例 #5】
见附加文件中的 city/city5.in 与 city/city5.ans。
该样例满足测试点 141414 的限制。
【样例 #6】
见附加文件中的 city/city6.in 与 city/city6.ans。
该样例满足测试点 202020 的限制。
【数据范围】
对于 100%100\%100% 的数据,2≤n≤2×1052 \le n \le 2\times10^52≤n≤2×105,1≤q≤2×1051 \le q \le 2\times10^51≤q≤2×105,1≤ui,vi,ki≤n1 \le u_i,v_i,k_i \le n1≤ui,vi,ki≤n,1≤ci,wi≤1061 \le c_i,w_i \le 10^61≤ci,wi≤106,保证从任意一个城市出发,都能通过原本存在的 n−1n-1n−1 条双向道路,到达任意一个城市。
| 测试点编号 | n≤n \len≤ | q≤q \leq≤ | 特殊性质 |
|---|---|---|---|
| 1∼31\sim31∼3 | 808080 | 808080 | 无 |
| 4∼74\sim74∼7 | 500050005000 | 500050005000 | 无 |
| 8∼108\sim108∼10 | 500050005000 | 2×1052\times10^52×105 | 无 |
| 11∼1311\sim1311∼13 | 2×1052\times10^52×105 | 2×1052\times10^52×105 | A |
| 14∼1614\sim1614∼16 | 2×1052\times10^52×105 | 2×1052\times10^52×105 | B |
| 17∼2017\sim2017∼20 | 2×1052\times10^52×105 | 2×1052\times10^52×105 | 无 |
特殊性质 A:保证对于所有的 1≤i<n1 \le i \lt n1≤i<n,都有 ui=i,vi=i+1u_i=i,v_i=i+1ui=i,vi=i+1。
特殊性质 B:保证对于所有的 1≤i≤q1 \le i \le q1≤i≤q,都有 ki=1k_i=1ki=1。
C++实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,mod=998244353;
int n,q,to[N<<1],nxt[N<<1],c[N<<1],head[N],cnt,fa[N],siz[N];
ll f[N],g[N],sf[N],sg[N],sumg;
void add(int u,int v,int w){
to[++cnt]=v;
nxt[cnt]=head[u];
c[cnt]=w;
head[u]=cnt;
}
void init(int u,int fat){
siz[u]=1,fa[u]=fat;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fa[u]) continue;
init(v,u);
siz[u]=siz[u]+siz[v];
}
}
void dfs(int u){
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fa[u]) continue;
f[v]=1ll*(siz[v]+1)*(n-siz[v])%mod*c[i]*2%mod;
g[v]=1ll*siz[v]*(n-siz[v]+1)%mod*c[i]*2%mod;
sf[v]=(f[v]+sf[u])%mod;
sg[v]=(g[v]+sg[u])%mod;
sumg=(sumg+g[v])%mod;
dfs(v);
}
}
int main(){
ios::sync_with_stdio(0);
int u,v,k,w;
ll ans1,ans2,ans3;
cin>>n>>q;
for(int i=1;i<n;i++) cin>>u>>v>>w,add(u,v,w),add(v,u,w);
init(1,0);
dfs(1);
for(int tmp=0;tmp<q;tmp++){
cin>>k>>w;
ans1=sf[k];
ans2=sumg-sg[k];
ans3=2ll*n*w;
cout<<(ans1+ans2+ans3+mod)%mod<<endl;
}
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
更多推荐
所有评论(0)