VP 记录 - 2022 ICPC 亚洲区域赛 (济南)

比赛链接

进度: 5 / 13

题目概览

题号 1 标题 2 做法
A Tower
*B Torch
C DFS Order 2
D Frozen Scoreboard
E Identical Parity
*F Grid Points
*G Quick Sort
*H Set of Intervals
*I Shortest Path
*J Skills
K Stack Sort
*L Tree Distance
M Best Carry Player

官方题解

A - Tower

解题思路

复杂度

代码参考

Show code

A.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <bits/stdc++.h>
using ll = long long;
using i64 = ll;
template <typename... Ts>
void dec(Ts &...x) {
((--x), ...);
}
template <typename... Ts>
void inc(Ts &...x) {
((++x), ...);
}
using namespace std;
void solve(int t_ = 0) {
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; ++i) cin >> a[i];
vector<int> b;
for (int i = 0; i < n; ++i) {
int x = a[i];
while (x) b.push_back(x), x /= 2;
}
sort(b.begin(), b.end());
b.erase(unique(b.begin(), b.end()), b.end());
auto dis = [](i64 a, i64 b) {
if (a >= b) return a - b;
i64 ret = b - a, t = 0;
while (b > a) {
b /= 2, ++t;
ret = min(ret, t + abs(a - b));
}
return ret;
};
i64 ans = INT64_MAX;
for (auto x : b) {
vector<i64> ret;
for (auto y : a) ret.push_back(dis(x, y));
sort(ret.begin(), ret.end());
i64 rett = 0;
for (int i = 0; i < n - m; ++i) rett += ret[i];
ans = min(ans, rett);
}
cout << ans << '\n';
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr << std::fixed << std::setprecision(6);
int i_ = 0;
int t_ = 0;
std::cin >> t_;
for (i_ = 0; i_ < t_; ++i_) solve(i_);
return 0;
}

B - Torch

解题思路

复杂度

代码参考

Show code

C - DFS Order 2

解题思路

复杂度

代码参考

Show code

C.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <bits/stdc++.h>
using ll = long long;
template <typename... Ts>
void dec(Ts &...x) {
((--x), ...);
}
template <typename... Ts>
void inc(Ts &...x) {
((++x), ...);
}
using namespace std;
const int MOD = 998244353;
void solve(int t_ = 0) {
int n;
cin >> n;
vector<vector<int>> e(n + 1);
vector<int> sz(n + 1), son(n + 1);
vector<ll> fac(n + 1);
fac[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i % MOD;
for (int i = 1, u, v; i < n; ++i)
cin >> u >> v, e[u].push_back(v), e[v].push_back(u);
auto dfs = [&](auto &&dfs, int u, int fa) -> ll {
sz[u] = 1;
ll ret = 1;
for (auto v : e[u])
if (v != fa) {
++son[u];
(ret *= dfs(dfs, v, u)) %= MOD;
sz[u] += sz[v];
}
return ret * fac[son[u]] % MOD;
};
vector<vector<ll>> dp(n + 1, vector<ll>(n + 1));
dp[1][1] = dfs(dfs, 1, 0);
auto dfs1 = [&](auto &&dfs1, int u, int fa) -> void {
vector<vector<ll>> dp1(son[u] + 1, vector<ll>(sz[u] + 1));
int tot = 0, szz = 0;
dp1[0][0] = 1;
for (auto v : e[u])
if (v != fa) {
tot++, szz += sz[v];
for (int i = tot; i >= 1; --i)
for (int j = szz; j >= sz[v]; --j)
(dp1[i][j] += dp1[i - 1][j - sz[v]]) %= MOD;
}
for (auto v : e[u])
if (v != fa) {
for (int i = 1; i <= tot; ++i)
for (int j = sz[v]; j <= szz; ++j)
(dp1[i][j] += MOD - dp1[i - 1][j - sz[v]]) %= MOD;
vector<ll> f(sz[u] + 1);
for (int i = 0; i <= sz[u] - sz[v]; ++i)
for (int j = 0; j < son[u]; ++j)
(f[i + 1] +=
dp1[j][i] * fac[j] % MOD * fac[son[u] - j - 1] % MOD) %= MOD;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= sz[u]; ++j) {
if (i + j > n) break;
(dp[v][i + j] += dp[u][i] * f[j] % MOD) %= MOD;
}
for (int i = tot; i >= 1; --i)
for (int j = szz; j >= sz[v]; --j)
(dp1[i][j] += dp1[i - 1][j - sz[v]]) %= MOD;
}
for (auto v : e[u])
if (v != fa) dfs1(dfs1, v, u);
};
dfs1(dfs1, 1, 0);
auto KSM = [&](ll x, ll p = 998244351) {
ll ret = 1;
while (p) {
if (p & 1) ret = ret * x % MOD;
x = x * x % MOD, p >>= 1;
}
return ret;
};
for (int i = 1; i <= n; ++i) {
ll sum = 0;
for (int j = 1; j <= n; ++j) (sum += dp[i][j]) %= MOD;
for (int j = 1; j <= n; ++j)
cout << dp[i][j] * dp[1][1] % MOD * KSM(sum) % MOD << " \n"[j == n];
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr << std::fixed << std::setprecision(6);
int i_ = 0;
solve(i_);
return 0;
}

D - Frozen Scoreboard

解题思路

复杂度

代码参考

Show code

D.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <bits/stdc++.h>
using ll = long long;
template <class T>
using vc = std::vector<T>;
#define for_(i, l, r, v...) for (ll i = (l), i##e = (r), ##v; i <= i##e; ++i)
template <typename... Ts>
void dec(Ts &...x) {
((--x), ...);
}
template <typename... Ts>
void inc(Ts &...x) {
((++x), ...);
}
using namespace std;
stringstream ss;
struct Node {
int m;
vc<tuple<int, int, int>> t;
vc<tuple<int, int>> frozen;
vc<string> state;
vc<bool> vis, chosen;
Node(int m): m(m), t(), state(m), vis(m), chosen(m) {}
void parse() {
for_(i, 0, m - 1) {
ss.clear();
ss << state[i];
char op;
ss >> op;
if (op == '.') continue;
if (op == '-') {
int x;
ss >> x;
t.emplace_back(i, x, -1);
continue;
}
if (op == '+') {
int x, y;
ss >> x;
ss.get();
ss >> y;
t.emplace_back(i, x, y);
continue;
}
int x, y;
ss >> x >> y;
t.emplace_back(i, y - x, -1);
frozen.emplace_back(t.size() - 1, x);
}
}
pair<int, ll> score() {
int cnt = 0;
ll tm = 0;
for (auto [_, x, i] : t)
if (i >= 0) {
tm += i + 20 * (x - 1);
++cnt;
}
return {cnt, tm};
}
bool valid(pair<int, ll> const &s) {
if (frozen.empty()) return score() == s;
pair target = score();
if (target > s) return 0;
int fac = s.first - target.first;
ll ftm = s.second - target.second;
for_(i, 0, (1 << frozen.size()) - 1) {
if (__builtin_popcountll(i) != fac) continue;
ll minftm = 240 * fac, rftm = 59 * fac, minsp = 0, rsp = 0;
for (int j = 0; j < frozen.size(); ++j) {
if (!(i & (1 << j))) continue;
auto &&[id_t, x] = frozen[j];
auto &&[id, cnt, tm] = t[id_t];
minsp += 20 * cnt;
rsp += 20 * (x - 1);
}
if (ftm < minftm + minsp || ftm > minftm + rftm + minsp + rsp) continue;
for (int j = 0; j < frozen.size(); ++j) {
if (i & (1 << j)) continue;
auto &&[id_t, x] = frozen[j];
auto &[id, cnt, tm] = t[id_t];
cnt += x;
}
for (int j = 0; j < frozen.size(); ++j) {
if (!(i & (1 << j))) continue;
auto &[id_t, x] = frozen[j];
auto &[id, cnt, tm] = t[id_t];
tm = 240;
++cnt;
--x;
}
ftm -= minftm + minsp;
if (ftm > rftm)
for (int j = 0; j < frozen.size(); ++j) {
if (!(i & (1 << j))) continue;
auto &&[id_t, x] = frozen[j];
auto &[id, cnt, tm] = t[id_t];
int _ = min<int>((ftm - rftm) / 20 + (rftm > 20), x);
cnt += _;
if ((ftm -= 20 * _) <= rftm) break;
}
if (ftm)
for (int j = 0; j < frozen.size(); ++j) {
if (!(i & (1 << j))) continue;
auto &&[id_t, x] = frozen[j];
auto &[id, cnt, tm] = t[id_t];
tm += min(59ll, ftm);
if (!(ftm -= min(59ll, ftm))) break;
}
return 1;
}
return 0;
}
void pnt() {
for (auto &i : state) i = ".";
for (auto [id, cnt, tm] : t) {
string _;
ss.clear();
ss << cnt;
ss >> _;
if (tm == -1) state[id] = "- " + _;
else {
state[id] = "+ " + _ + '/';
ss.clear();
ss << tm;
ss >> _;
state[id] += _;
}
}
}
};
istream &operator>>(istream &is, Node &p) {
for (auto &i : p.state)
while (i.empty()) getline(cin, i);
return is;
}
ostream &operator<<(ostream &os, Node &p) {
p.pnt();
for (auto const &i : p.state) os << i << '\n';
return os;
}
void solve(int t_ = 0) {
int n, m;
cin >> n >> m;
for_(i, 1, n) {
pair<int, ll> score;
cin >> score.first >> score.second;
Node p(m);
cin >> p;
p.parse();
auto [x, y] = p.score();
if (!p.valid(score)) {
cout << "No\n";
continue;
}
cout << "Yes\n";
cout << p;
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr << std::fixed << std::setprecision(6);
int i_ = 0;
solve(i_);
return 0;
}

E - Identical Parity

解题思路

复杂度

代码参考

Show code

E.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>
using ll = long long;
template <typename... Ts>
void dec(Ts &...x) {
((--x), ...);
}
template <typename... Ts>
void inc(Ts &...x) {
((++x), ...);
}
using namespace std;
#define YES return void(cout << "YES\n")
#define NO return void(cout << "NO\n")
void solve(int t_ = 0) {
int n, k;
cin >> n >> k;
if (n == k) YES;
if (k == 1) NO;
if (!(k & 1)) YES;
if (n % k == 0) NO;
int _ = (k + 1) / 2;
ll b = 2ll * _ * _;
if (n >= b) NO;
int x = n / k;
if (n - x * k <= x - 2) NO;
if ((x + 1) * k - n <= x - 1) NO;
YES;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr << std::fixed << std::setprecision(6);
int i_ = 0;
int t_ = 0;
std::cin >> t_;
for (i_ = 0; i_ < t_; ++i_) solve(i_);
return 0;
}

F - Grid Points

解题思路

复杂度

代码参考

Show code

G - Quick Sort

解题思路

复杂度

代码参考

Show code

H - Set of Intervals

解题思路

复杂度

代码参考

Show code

I - Shortest Path

解题思路

复杂度

代码参考

Show code

J - Skills

解题思路

复杂度

代码参考

Show code

K - Stack Sort

解题思路

复杂度

代码参考

Show code

K.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>
template <typename... Ts>
void dec(Ts &...x) {
((--x), ...);
}
template <typename... Ts>
void inc(Ts &...x) {
((++x), ...);
}
using namespace std;
void solve(int t_ = 0) {
int n, cnt = 0;
cin >> n;
vector<int> a(n + 2, 0);
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
if (a[x + 1] == 1) {
} else {
++cnt;
}
a[x] = 1;
}
cout << cnt << "\n";
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr << std::fixed << std::setprecision(6);
int i_ = 0;
int t_ = 0;
std::cin >> t_;
for (i_ = 0; i_ < t_; ++i_) solve(i_);
return 0;
}

L - Tree Distance

解题思路

复杂度

代码参考

Show code

M - Best Carry Player

解题思路

复杂度

代码参考

Show code

M.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <bits/stdc++.h>
using ll = long long;
template <class T>
using vc = std::vector<T>;
template <typename... Ts>
void dec(Ts &...x) {
((--x), ...);
}
template <typename... Ts>
void inc(Ts &...x) {
((++x), ...);
}
using namespace std;
void solve(int t_ = 0) {
int n;
cin >> n;
vc<string> a(n);
for (auto &i : a) cin >> i, reverse(i.begin(), i.end());
auto x = a[0];
ll cnt = 0;
auto add = [&](string_view a, string_view b) {
if (a.size() > b.size()) swap(a, b);
string retc(b.size() + 1, '0');
for (int i = 0; i < b.size(); ++i) {
int aa = i < a.size() ? a[i] - 48 : 0, bb = b[i] - 48;
if (aa + bb + retc[i] - 48 >= 10) {
++cnt;
retc[i] = retc[i] + aa + bb - 10;
retc[i + 1] += 1;
} else retc[i] = retc[i] + aa + bb;
}
while (retc.back() == '0') retc.pop_back();
return retc;
};
string now = a[0];
for (int i = 1; i < n; ++i) now = add(now, a[i]);
cout << cnt << '\n';
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr << std::fixed << std::setprecision(6);
int i_ = 0;
int t_ = 0;
std::cin >> t_;
for (i_ = 0; i_ < t_; ++i_) solve(i_);
return 0;
}

  1. 打 * 的是还没写的题↩︎

  2. 带超链接的是找到了原题或原型↩︎