Codeforces Round 975 (Div. 2)
C. Cards Partition (C)#
对于每个确定的size,有便捷的方法判断该值是否合法:组数最小为 \(a_{max}\),若 \(k\) 张牌可以填出 \(a_{max}\) 组牌堆则合法;将余下的牌当成新的一组,若 \(k\) 张牌可以凑出一整组则合法;其余情况不合法。由于check过程为 \(O(1)\),可从大到小暴力枚举size,时间复杂度 \(O(n)\).
void solve() { scanf("%d%lld", &n, &k); sum = maxn = 0; for(int i = 1; i <= n; i++) { scanf("%lld", &a[i]); sum += a[i]; maxn = max(maxn, a[i]); } for(int i = n; i; i--) { if(sum + k < i * maxn) continue; ll ss = i * maxn; if(ss >= sum) { printf("%d\n", i); return; } ll lst = sum % i; if(lst == 0 || k + lst >= i) { printf("%d\n", i); return; } } }
D. Speedbreaker (D)#
(搞了个假做法没写出来,6)
当 \(t = i\) 时,找到 \(a\leq i\) 的最左侧与最右侧城市,其间的所有城市都必须在 \(t\) 时间内到达。具体地,设两侧城市为 \(l,r\),则到 \(l, r\) 位置距离之和 \(\leq i\) 的所有城市可能成为起点,差分处理即可。最后求缀和检查每个位置被多少合法区间所覆盖,被全部区间覆盖的城市即合法起点。
void solve() { int n; scanf("%d", &n); fill(s + 1, s + n + 1, 0); fill(l + 1, l + n + 1, 0); for(int i = 1; i <= n; i++) { int x; scanf("%d", &x); if(!l[x]) l[x] = i; r[x] = i; } int L = 1e9, R = 0; for(int i = 1; i <= n; i++) { if(l[i]) { L = min(L, l[i]), R = max(R, r[i]); l[i] = L, r[i] = R; } } int cnt = 0, ans = 0; for(int i = 1; i <= n; i++) { if(l[i]) { int L = max(1, r[i] - i + 1); int R = min(n, l[i] + i - 1); if(R - L + 1 < i) { printf("0\n"); return; } s[L]++, s[R + 1]--, cnt++; } } for(int i = 1; i <= n; i++) { s[i] += s[i - 1]; if(s[i] == cnt) ans++; } printf("%d\n", ans); }
E. Tree Pruning (E)#
一个点被砍掉有两种可能:最终树深度小于其深度,或者最终树深度大于其最深叶子节点的深度。与D同理,差分+前缀和求解,取前缀和最小值。
int dfs(int f, int i) { tar[i] = dep[i] = dep[f] + 1; for(int t : v[i]) { if(t == f) continue; tar[i] = max(tar[i], dfs(i, t)); } return tar[i]; } void solve() { int n; scanf("%d", &n); for(int i = 1; i <= n; i++) { v[i].clear(); sum[i] = 0; } for(int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); v[x].push_back(y); v[y].push_back(x); } dfs(0, 1); for(int i = 1; i <= n; i++) { sum[1]++; sum[dep[i]]--; sum[tar[i] + 1]++; } int ans = 1e9; for(int i = 1; i <= n; i++) { sum[i] += sum[i - 1]; ans = min(ans, sum[i]); } printf("%d\n", ans); }
F. Max Plus Min Plus Size (F)#
在最小值确定的情况下,对于一段连续序列,选择包含最大值的所有奇数或偶数位置是最优的,即红色数字数量为 \(s / 2\)(s为奇数且最大值在偶数位置)或 \((s + 1) / 2\). 从大至小枚举最小值,用并查集维护所有连续序列,每次将当前最小值加入并查集中,动态维护当前的数字数量与最大值的奇偶位置即可。
const int N = 2e5 + 10; int a[N], f[N], sz[N]; int find(int i) { if(f[i] == i) return i; return f[i] = find(f[i]); } map <int, vector <int> > mp; void solve() { int n; scanf("%d", &n); mp.clear(); int maxn = 0; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); mp[-a[i]].push_back(i); f[i] = i, sz[i] = 1; maxn = max(maxn, a[i]); } int ans = 0, sum = 0, flag = 0; for(auto x : mp) { int minn = -x.first; for(int t : x.second) { if(t > 1 && t < n && a[t - 1] >= a[t] && a[t + 1] > a[t]) { int lf = find(t - 1), rf = find(t + 1); int l = t - sz[lf]; if(a[lf] == maxn && ((sz[lf] & 1) == 0 || ((lf - l + 1) & 1))) flag--; if(a[rf] == maxn && ((sz[rf] & 1) == 0 || ((rf - t) & 1))) flag--; sum -= (sz[lf] + 1) / 2; sum -= (sz[rf] + 1) / 2; if(a[lf] > a[rf]) swap(lf, rf); sz[rf] += sz[lf] + 1; sum += (sz[rf] + 1) / 2; f[lf] = f[t] = rf; if(a[lf] == maxn && a[rf] == maxn && ((lf & 1) != (rf & 1))) flag = 1e9; if(a[rf] == maxn && ((sz[rf] & 1) == 0 || ((rf - l + 1) & 1))) flag++; } else if(t > 1 && a[t - 1] >= a[t]) { int lf = find(t - 1); int l = t - sz[lf]; if(a[lf] == maxn && ((sz[lf] & 1) == 0 || ((lf - l + 1) & 1))) flag--; sum -= (sz[lf] + 1) / 2; sz[lf]++; sum += (sz[lf] + 1) / 2; f[t] = lf; if(a[t] == maxn && a[lf] == maxn && ((lf & 1) != (t & 1))) flag = 1e9; if(a[lf] == maxn && ((sz[lf] & 1) == 0 || ((lf - l + 1) & 1))) flag++; } else if(t < n && a[t + 1] > a[t]) { int rf = find(t + 1); int l = t; if(a[rf] == maxn && ((sz[rf] & 1) == 0 || ((rf - t) & 1))) flag--; sum -= (sz[rf] + 1) / 2; sz[rf]++; sum += (sz[rf] + 1) / 2; f[t] = rf; if(a[t] == maxn && a[rf] == maxn && ((rf & 1) != (t & 1))) flag = 1e9; if(a[rf] == maxn && ((sz[rf] & 1) == 0 || ((rf - l + 1) & 1))) flag++; } else { sum++; if(a[t] == maxn) flag++; } } int ss = sum + maxn + minn; if(!flag) ss--; ans = max(ans, ss); } printf("%d\n", ans); }
作者:Aderose_yr
出处:https://www.cnblogs.com/meowqwq/p/18441851
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
喵喵喵)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现