点击输入文字 - P14467 Sol
HDS_Acenaphthylene · · 题解
注意到每个人扔给的人是固定的,所以
球是沿着基环树森林传递的,可以联想到一个 Trick:在基环树上倍增,求出
rep(j, 1, 31) rep(i, 1, n) st[i][j] = st[st[i][j - 1]][j - 1];
我们将
rep(j, 0, 30) if(k & (1 << j)) {
rep(i, 1, n) f[i] = 0;
rep(i, 1, n) f[st[i][j]] += a[i];
rep(i, 1, n) a[i] = f[i];
}
P.S.:这题出在某校模拟赛里,然后我因为输出用换行隔开而非空格狂砍 -38 分。
code:
# include<bits/stdc++.h>
# define rep(i,a,b) for(int i = (a);i <= (b);i ++)
# define dwn(i,a,b) for(int i = (a);i >= (b);i --)
# define fid(i,a,F) for(int i = (a);F;i ++)
# define int32 int
# define int64 long long
# define int16 short
# define dbg(x) std::cerr << #x << ":" << x <<"\n";
# define FaILurEg(s) std::freopen(s".in","r", stdin);std::freopen(s".out","w",stdout);
# define ___main int32 main()
using std::cin;using std::cout;
int n, k, a[100005], st[100005][32], f[100005];
___main {
// FaILurEg("krugo");
std::ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> k;rep(i, 1, n) cin >> a[i];rep(i, 1, n) cin >> st[i][0];
rep(j, 1, 31) rep(i, 1, n) st[i][j] = st[st[i][j - 1]][j - 1];
rep(j, 0, 30) if(k & (1 << j)) {
rep(i, 1, n) f[i] = 0;
rep(i, 1, n) f[st[i][j]] += a[i];
rep(i, 1, n) a[i] = f[i];
}
int mx = 0; rep(i, 1, n) mx = std::max(mx, a[i]);cout << mx << "\n";
rep(i, 1, n) if(a[i] == mx) cout << i << "\n";
}