A. FizzBuzz Remixed
题意:求\([0, n]\)里有多少数模3和模5的值一样。
我是打表发现每15个数的开头3个数满足要求。
点击查看代码
void solve() {int n;std::cin >> n;std::cout << n / 15 * 3 + std::min(n % 15 + 1, 3) << "\n";
}
B. Robot Program
题意:坐标轴上从起点按照给定指令序列按顺序执行,如果到了0这个位置就从头开始执行指令,问\(k\)次指令后经过了几次0。
\(k\)很大,但如果我们经过0,就会陷入一个循环。于是先求几步可以到0,然后在计算从0到0这个循环需要几步,就可以之间计算还有多少个循环可以执行。
点击查看代码
void solve() {i64 n, x, k;std::cin >> n >> x >> k;std::string s;std::cin >> s;i64 ans = 0;for (int i = 0; x != 0 && i < n && k; ++ i) {-- k;if (s[i] == 'L') {-- x;} else {++ x; }} if (x == 0) {++ ans;for (int i = 0; i < n; ++ i) {if (s[i] == 'L') {-- x;} else {++ x; }if (x == 0) {ans += k / (i + 1);break;}}}std::cout << ans << "\n";
}
C. Limited Repainting
题意:一个序列初始都是R,每个位置有一个价值。你可以选择\(k\)个区间把位置都变成B,有一个最终序列\(s\),如果最后你的序列和\(s\)有不一样的地方,代价就是不一样的地方的价值的最大值。求最小代价。
二分答案,如果\(s[i] = R\) && \(a[i] > mid\)则这个位置绝对不能选。否则其它可以选的位置就是一段段区间,如果一个区间有一个\(s[i] = B\) && \(a[i] > mid\)的地方就必须选。看必须选的区间数是不是小于等于\(k\)。
点击查看代码
void solve() {int n, k;std::cin >> n >> k;std::string s;std::cin >> s;std::vector<int> a(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}auto check = [&](int x) -> int {std::vector<int> b(n);for (int i = 0; i < n; ++ i) {if (s[i] == 'B') {b[i] = 1;} else if (s[i] == 'R' && a[i] <= x) {b[i] = 1;}}int cnt = 0;for (int i = 0; i < n; ++ i) {if (b[i] == 1) {int j = i;bool flag = s[i] == 'B' && a[i] > x;while (j + 1 < n && b[j + 1] == 1) {++ j;flag |= s[j] == 'B' && a[j] > x;}if (flag) {++ cnt;}i = j;}}return cnt <= k;};int l = 0, r = 1e9;while (l < r) {int mid = l + r >> 1;if (check(mid)) {r = mid;} else {l = mid + 1;}}std::cout << l << "\n";
}
D. Tree Jumps
题意:给你一棵树,根可以到其中任意一个儿子,但从深度为2的点开始,每个点只能去深度比它大一的点,且这个点不是它到儿子。求从根开始的不同路径树。
类似\(DAG\)图路径计数,我们只能一层一层走,那么我们就一层一层算,当前点可以从上一层除了父亲过了,那么记录到达每个点的路径数\(f\),以及每一层的点的路径数总和\(sum\),则以该点为终点的路径数为\(sum - f_{p_i}\)。其中\(p_i\)是\(i\)的父亲。
代码省略了取模类
点击查看代码
void solve() {int n;std::cin >> n;std::vector<std::vector<int>> adj(n);std::vector<int> p(n);for (int i = 1; i < n; ++ i) {std::cin >> p[i];-- p[i];adj[p[i]].push_back(i);}std::vector<int> d(n);std::vector<std::vector<int>> g(n);auto dfs = [&](auto self, int u) -> void {g[d[u]].push_back(u);for (auto & v : adj[u]) {d[v] = d[u] + 1;self(self, v);}};dfs(dfs, 0);std::vector<Z> f(n);Z sum = 0;for (auto & u : adj[0]) {f[u] = 1;sum += 1;}Z ans = sum + 1;for (int i = 2; i < n; ++ i) {Z t = 0;for (auto & u : g[i]) {f[u] = sum - f[p[u]];t += f[u];}sum = t;ans += t;}std::cout << ans << "\n";
}