A. Count Takahashi
模拟
代码实现
n = int(input()) ans = 0 for i in range(n): s = input() if s == 'Takahashi': ans += 1 print(ans)
B. Couples
统计有多少个数对 满足 即可
代码实现
n = int(input()) a = list(map(int, input().split())) print(sum(a[i] == a[i+2] for i in range(n*2-2)))
C. Tile Distance 2
注意到,上下移动一格,不会产生费用的左右边界就会各增加 。因此,如果在调整纵坐标的时候,如果目标在这个范围之外,那么就向横向移动即可。
代码实现
sx, sy = map(int, input().split()) tx, ty = map(int, input().split()) if (sx+sy)%2 == 1: sx -= 1 if (tx+ty)%2 == 1: tx -= 1 x = abs(tx-sx) y = abs(ty-sy) ans = 0 if x < y: ans = y else: ans = (x+y)//2 print(ans)
D. Avoid K Palindrome
在满足条件的字符串末尾添加一个字符是否仍然满足条件,只需知道最后的 个字符即可
记 dp[i][S]
表示考虑到第 个字符且末尾的 个字符构成的字符串为 的合法方案数
代码实现
#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 mint = modint998244353; bool isPalindrome(string s) { string ns = s; reverse(ns.begin(), ns.end()); return s == ns; } int main() { int n, k; string s; cin >> n >> k >> s; map<string, mint> dp; dp[""] = 1; rep(i, n) { map<string, mint> old; swap(dp, old); for (auto [t, num] : old) { for (char c = 'A'; c <= 'B'; ++c) { if (s[i] != '?' and s[i] != c) continue; string nt = t+c; if (nt.size() == k and isPalindrome(nt)) continue; if (nt.size() == k) nt.erase(nt.begin()); dp[nt] += num; } } } mint ans; for (auto [t, num] : dp) ans += num; cout << ans.val() << '\n'; return 0; }
E. Water Tank
这题本质上是单调栈求最大矩形的问题
首先可以表示出,第 格第一次有水是在:
考虑用单调栈来维护这个答案,单调栈维护一下当前后缀的最大值以及对应的区间长度即可。答案就是单调栈中所有元素的长度 高度之和
时间复杂度为
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; using P = pair<ll, ll>; int main() { int n; cin >> n; vector<int> h(n); rep(i, n) cin >> h[i]; stack<P> st; ll now = 0; vector<ll> ans(n); rep(i, n) { ll w = 1; while (st.size() and st.top().first <= h[i]) { auto [nh, nw] = st.top(); st.pop(); now -= nh*nw; w += nw; } st.emplace(h[i], w); now += h[i]*w; ans[i] = now+1; } rep(i, n) cout << ans[i] << ' '; return 0; }
F. Tree Degree Optimization
注意到如果要构成树,对于点 ,一定得满足以下性质:
那么我们不妨将所有点的度数初始化为 ,然后贪心地用小根堆来分摊掉剩下的 的度数
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; using P = pair<ll, int>; int main() { int n; cin >> n; vector<ll> a(n); rep(i, n) cin >> a[i]; ll ans = 0; rep(i, n) ans += a[i]; vector<int> d(n, 1); priority_queue<P, vector<P>, greater<P>> q; rep(i, n) q.emplace(a[i]*3ll, i); rep(ti, n-2) { auto [dif, i] = q.top(); q.pop(); ans += dif; d[i]++; q.emplace(a[i]*(d[i]*2+1), i); } cout << ans << '\n'; return 0; }
G. Sum of Tree Distance
本题有一堆做法:点分治、dsu on tree、虚树、根号分治
这里仅介绍点分治的做法:
把路径分为子树内部的和跨越重心的,子树内部的递归处理,跨越重心的就维护一下当前已经遍历到的所有子树的每种颜色到重心的距离和以及点的个数,然后直接计算贡献即可。时间复杂度为
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; using P = pair<int, int>; int main() { cin.tie(nullptr) -> sync_with_stdio(false); int n; cin >> n; 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> a(n); rep(i, n) cin >> a[i]; ll ans = 0; // centroid decomposition vector<bool> used(n); vector<int> sz(n); auto cd = [&](auto& cd, int v) -> void { // find centroid auto getCentroid = [&]() { auto dfs = [&](auto& f, int v, int p=-1) -> int { sz[v] = 1; for (int u : to[v]) { if (u == p or used[u]) continue; sz[v] += f(f, u, v); } return sz[v]; }; int tot = dfs(dfs, v), c = -1; auto dfs2 = [&](auto& f, int v, int p=-1) -> void { bool ok = (tot-sz[v])*2 <= tot; for (int u : to[v]) { if (u == p or used[u]) continue; f(f, u, v); if (sz[u]*2 > tot) ok = false; } if (ok) c = v; }; dfs2(dfs2, v); return c; }; int c = getCentroid(); used[c] = true; unordered_map<int, int> cnt; unordered_map<int, ll> sum; cnt[a[c]] = 1; sum[a[c]] = 0; for (int u : to[c]) { if (used[u]) continue; vector<P> ps; auto dfs = [&](auto& f, int v, int p=-1, int dep=1) -> void { ps.emplace_back(a[v], dep); for (int u : to[v]) { if (u == p or used[u]) continue; f(f, u, v, dep+1); } }; dfs(dfs, u); for (auto [col, dep] : ps) { ans += sum[col] + (ll)dep*cnt[col]; } for (auto [col, dep] : ps) { cnt[col]++; sum[col] += dep; } } for (int u : to[c]) { if (used[u]) continue; cd(cd, u); } }; cd(cd, 0); cout << ans << '\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现