A. Cut
模拟
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n, k; cin >> n >> k; vector<int> a(n); rep(i, n) cin >> a[i]; rotate(a.begin(), a.begin()+(n-k), a.end()); rep(i, n) cout << a[i] << ' '; return 0; }
B. Decrease 2 max elements
模拟
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; cin >> n; vector<int> a(n); rep(i, n) cin >> a[i]; int ans = 0; while (1) { ranges::sort(a, greater<>()); if (a[1] <= 0) break; a[0]--; a[1]--; ans++; } cout << ans << '\n'; return 0; }
C. Triple Attack
周期性
把 {1, 1, 3} 看成是一个组合技,用这 次攻击可以让敌人掉 点血
对每个敌人先尽可能地用组合技,如果还有剩余血量,就暴力模拟即可
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; int main() { int n; cin >> n; vector<int> h(n); rep(i, n) cin >> h[i]; ll t = 0; rep(i, n) { int x = h[i]/5; t += x*3; h[i] -= x*5; while (h[i] > 0) { t++; if (t%3 == 0) h[i] -= 3; else h[i]--; } } cout << t << '\n'; return 0; }
D. Minimum Steiner Tree
显然应该从叶子节点开始删,可以考虑以某个关键点跑dfs
一个点被保留当且仅当以它为根的子树中包含关键点
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n, k; cin >> n >> k; vector<vector<int>> to(n); rep(i, n-1) { int a, b; cin >> a >> b; --a; --b; to[a].push_back(b); to[b].push_back(a); } vector<int> vs(k); rep(i, k) cin >> vs[i], vs[i]--; vector<bool> selected(n); rep(i, k) selected[vs[i]] = true; vector<int> num(n); auto dfs = [&](auto& f, int v, int p=-1) -> void { if (selected[v]) num[v]++; for (int u : to[v]) { if (u == p) continue; f(f, u, v); num[v] += num[u]; } }; dfs(dfs, vs[0]); int ans = 0; rep(i, n) if (num[i] > 0) ans++; cout << ans << '\n'; return 0; }
E. Train Delay
注意到,
于是,可以得到
可以按 递增的顺序来求出所有的 ,暴力模拟的时间复杂度为
下面考虑优化:
对每个站点维护一个二元组序列 的信息
对于 ,可以开一个数组 maxT
来维护, 就表示到站时间在当前火车的发车时间之前且目的地在站点 处的
可以考虑用小根堆来维护每个站点的二元组序列,这样就能保证 单调递增了
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using P = pair<int, int>; using PQ = priority_queue<P, vector<P>, greater<P>>; struct Train { int a, b, s, t, i; Train(int a, int b, int s, int t, int i): a(a), b(b), s(s), t(t), i(i) {} bool operator<(const Train& o) const { return s < o.s; } }; int main() { int n, m, x1; cin >> n >> m >> x1; vector<Train> trains; rep(i, m) { int a, b, s, t; cin >> a >> b >> s >> t; --a; --b; trains.emplace_back(a, b, s, t, i); } sort(trains.begin(), trains.end()); vector<int> x(m); vector<int> maxT(n); vector<PQ> q(n); for (auto [a, b, s, t, i] : trains) { if (i == 0) x[i] = x1; else { while (q[a].size()) { auto [nt, val] = q[a].top(); if (nt > s) break; q[a].pop(); maxT[a] = max(maxT[a], val); } x[i] = max(0, maxT[a]-s); } q[b].emplace(t, t+x[i]); } rep(i, m) if (i) cout << x[i] << ' '; return 0; }
F. Dividing Game
对每个数求一遍 函数,打表可以发现 就是 的可重复质因子集合的大小,然后直接套 定理即可
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { const int M = 100005; vector<int> g(M); for (int i = 1; i < M; ++i) { int now = 0; int x = i; for (int d = 2; d*d <= x; ++d) { if (x%d != 0) continue; while (x%d == 0) now++, x /= d; } if (x != 1) now++; g[i] = now; } int n; cin >> n; int x = 0; rep(i, n) { int a; cin >> a; x ^= g[a]; } if (x == 0) puts("Bruno"); else puts("Anna"); return 0; }
G. Add and Multiply Queries
黑体字是突破口,注意到询问3的答案不超过 就很简单了
如果区间 中的 的个数超过 个,那么执行乘法运算的话显然会超过 ,所以我们可以大胆断定区间中 的位置不超过 个
对于 的连续区间只需执行加法即可
考虑维护满足以下需求的数据结构:
- 求出下一个满足 的位置
std::set
- 区间中 的累加和 树状数组
代码实现
#include <bits/stdc++.h> #if __has_include(<atcoder/all>) #include <atcoder/all> using namespace atcoder; #endif #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; int main() { cin.tie(nullptr) -> sync_with_stdio(false); int n; cin >> n; vector<int> a(n), b(n); rep(i, n) cin >> a[i]; rep(i, n) cin >> b[i]; fenwick_tree<ll> d(n); rep(i, n) d.add(i, a[i]); set<int> st; rep(i, n) if (b[i] > 1) st.insert(i); st.insert(n); int q; cin >> q; rep(qi, q) { int type; cin >> type; if (type == 3) { int l, r; cin >> l >> r; --l; ll v = 0; while (l < r) { int i = *st.lower_bound(l); i = min(i, r); v += d.sum(l, i); if (i == r) break; v = max(v+a[i], v*b[i]); l = i+1; } cout << v << '\n'; } else { int i, x; cin >> i >> x; --i; if (type == 1) { d.add(i, x-a[i]); a[i] = x; } else { b[i] = x; if (b[i] > 1) st.insert(i); else st.erase(i); } } } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】