当前位置: 首页 > news >正文

杂题选记(10.26 - 11.1)

P12029 [USACO25OPEN] Election Queries G

\(c_i\) 为投票给 \(i\) 的人数。那么两头奶牛 \(x\)\(y\) 能成为领队的条件是 \(c_x + c_y \ge c_max\),其中 \(c_max = \max{c_i}\)
考虑单次查询,用双指针可以轻松地做到 \(O(n)\),二分带个 \(\log\) 也可以接受的。
卡在了一个重要结论,由于 \(\sum{c_i} = n\),那么不同的 \(c_i\) 的取值最多有 \(O(\sqrt{n})\)\(1 + 2 + \cdots + n = \frac{n(n + 1)}{2}\))。
那么我们开 \(N\)\(set\) 记录 \(c_x = i\) 中最小/最大的 \(x\),然后每次对还存在的 \(c_i\) 做一遍尺取就好了。
复杂度 \(O(Q{\log{N} + \sqrt{N}})\)

Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
set<int> s, mn[N];
set<int, greater<int> > mx[N];
int c[N], a[N], n, q;
void upd(int x, int k){if(c[x]){mx[c[x]].erase(x), mn[c[x]].erase(x);if(mx[c[x]].empty()) s.erase(c[x]);}c[x] += k;if(c[x]){mx[c[x]].insert(x), mn[c[x]].insert(x);if(mx[c[x]].size() == 1) s.insert(c[x]);}
}
int qry(){auto l = s.begin(), r = s.end();int mny = 1e9, cmax = *s.rbegin(), ans = 0;
//	cout << cmax << '\n';while(l != s.end()){while(r != s.begin() && *prev(r) + *l >= cmax) --r, mny = min(mny, *mn[*r].begin());ans = max(ans, *mx[*l].begin() - mny);++l;}return ans;
}
int main(){cin.tie(nullptr)->sync_with_stdio(0);cin >> n >> q;for(int i = 1; i <= n; ++i) cin >> a[i], c[a[i]]++;for(int i = 1; i <= n; ++i){if(c[i]) s.insert(c[i]), mx[c[i]].insert(i), mn[c[i]].insert(i);}while(q--){int x, k;cin >> x >> k;upd(a[x], -1);a[x] = k;upd(a[x], 1);cout << qry() << '\n';}return 0;
}

P12030 [USACO25OPEN] OohMoo Milk G

怎么说呢,感觉这题很玄乎。
可以发现,Fj 每天的操作就是对最大的 \(A\) 个数 + 1,然后 Nj 的操作就是对最大的 \(B\) 个数 - 1。
我们发现 Fj 每天加的那 \(A\) 个数总是固定的,就是原序列中最大的 \(A\) 个数。那么现在难点在于 Nj 的操作。
先考虑对前 \(A\) 大的数全部加 \(D\)。对于一些特别大的数,Nj 每次操作都会选择减他们,相当于这些数占用了一些固定的位置。但对于一些更小的数来说,我们要最小化 \(\sum x^{2}\),根据凸性/均值,让他们更加平均是更优的。那么就类似云浅那场的 T2。我们考虑二分这个平均值 \(k\),对于 \(a_i > k + D\) 的,这就是那些每次都必须减的数,会耗费 \(D\) 个操作次数。而对于其他的 \(a_i > k\),我们会耗费 \(a_i - k\) 的操作次数把他们全部都调成这个平均值 \(k\)。由于题目限制总共操作次数不得超过 \(B \times D\)。我们找到最大的 \(k\) 使得操作次数刚好 \(\ge B \times D\)。假设 \(k\) 时耗费的次数是 \(check(k)\),根据上面调整的过程,不难发现我们二分出的这个 \(k\),它的 \(check(k) - B \times D < B\)。之所以会有这些超的,是因为整数均值就是一些是 \(k\),一些是 \(k + 1\)。那么我们把多的那部分再调成 \(k + 1\) 即可。

Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5, mod = 1e9 + 7;
int n, d, a, b, m[N];
int check(int k){int cnt = 0;for(int i = 1; i <= a; ++i){if(m[i] > k) cnt += min(d, m[i] - k);}return cnt;
}
signed main(){ cin.tie(nullptr)->sync_with_stdio(0);cin >> n >> d >> a >> b;for(int i = 1; i <= n; ++i) cin >> m[i];sort(m + 1, m + 1 + n, greater<int>());for(int i = 1; i <= a; ++i) m[i] += d;int l = 1, r = 2e9;while(l < r){int mid = (l + r + 1) >> 1;if(check(mid) < b * d) r = mid - 1;else l = mid;}int k = check(l) - b * d, ans = 0;for(int i = 1; i <= n; ++i){if(m[i] > l) m[i] -= min(d, m[i] - l);(ans += m[i] * m[i]) %= mod; }(ans += k * (2 * l + 1)) %= mod;cout << ans;return 0;
}

CF2150B Grid Counting

卡在了怎么处理 \(\max(x_i, y_i) = k\) 的条件上。事实上,可以把每个点的 \(\max(x_i, y_i)\) 画出来,发现是从左上角一圈一圈递增;同理,\(\max(x_i, n - y_i + 1)\) 是从右上角一圈一圈递增。稍微找一下规律,可以发现最终能涂色的那一部分是一个倒三角状物,那么再根据 \(a_i\) 的限制从下往上填算方案就好。

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5, mod = 998244353;
ll a[N], n, k, fac[N], ifac[N], inv[N];
ll C(int n, int m){if(m > n || n < 0) return 0;return fac[n] * ifac[m] % mod * ifac[n - m] % mod;}
void solve(){cin >> n;k = 0;for(int i = 1; i <= n; ++i) cin >> a[i], k += a[i];if(k != n || a[1] < 2) cout << 0 << '\n';else{ll ans = 1, cnt = 0;for(int i = (n + 1) / 2; i >= 1; --i){ans = (ans * C(n - 2 * (i - 1) - cnt, a[i])) % mod;cnt += a[i];}for(int i = (n + 1) / 2 + 1; i <= n; ++i){if(a[i] != 0){ ans = 0; break; }}cout << ans << '\n';}
}
int main(){cin.tie(nullptr)->sync_with_stdio(0);fac[0] = fac[1] = ifac[0] = ifac[1] = inv[1] = 1;for(int i = 2; i <= 2e5; ++i){fac[i] = (fac[i - 1] * i) % mod;inv[i] = ((mod - mod / i) * inv[mod % i]) % mod;ifac[i] = (ifac[i - 1] * inv[i]) % mod;}int T; cin >> T;while(T--) solve();return 0;
}

CF2150C Limited Edition Shop

推等价条件:记 \(i\)\(b_i\) 中出现的位置是 \(pos_i\),那么 Alice 能从她喜爱的物品中选出一个子集 \(S\) 的条件是 \(\forall a_i \notin S, a_j \in S, i < j, pos_{a_i} < pos_{a_j}\)
考虑 dp,\(f_{i, j}\) 表示 Alice 选到前 \(i\) 个物品,之前没选的物品中最大的 \(pos_{a_k}(k \le i) = j\) 的最大值。
\(\begin{cases} f_{i + 1, j} \gets f_{i, j} + v_{a_i + 1} & j < pos_{a_i + 1} \\ f_{i + 1, j} \gets \max_{k < j}{f_{i, k}} & j = pos_{a_i + 1} \\ f_{i + 1, j} \gets f_{i, j} & j > pos_{a_i + 1} \\ \end{cases}\)
考虑线段树直接维护 \(f_j\)。从 \(i \to i + 1\) 时,发现 \(f_j\) 的转移是一段区间加,一次区间查最大值,和一次单点修改。

Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5, inf = 1e18;
int n, v[N], a[N], b[N], pos[N], tag[N << 2], tr[N << 2];
#define ls(p) p << 1
#define rs(p) p << 1 | 1
void pushup(int p){ tr[p] = max(tr[ls(p)], tr[rs(p)]); }
void addtag(int p, int k){ tag[p] += k, tr[p] += k; }
void pushdown(int p){ if(tag[p]) addtag(ls(p), tag[p]), addtag(rs(p), tag[p]), tag[p] = 0; }
void add(int L, int R, int k, int p = 1, int pl = 0, int pr = n){if(L <= pl && R >= pr) return addtag(p, k);int mid = (pl + pr) >> 1;pushdown(p);if(L <= mid) add(L, R, k, ls(p), pl, mid);if(R > mid) add(L, R, k, rs(p), mid + 1, pr);pushup(p); 
}
void upd(int x, int k, int p = 1, int pl = 0, int pr = n){if(pl == pr) return tr[p] = k, void();int mid = (pl + pr) >> 1;pushdown(p);if(x <= mid) upd(x, k, ls(p), pl, mid);else upd(x, k, rs(p), mid + 1, pr);pushup(p);
}
int query(int L, int R, int p = 1, int pl = 0, int pr = n){if(L <= pl && R >= pr) return tr[p];int mid = (pl + pr) >> 1, ret = -inf;pushdown(p);if(L <= mid) ret = query(L, R, ls(p), pl, mid);if(R > mid) ret = max(ret, query(L, R, rs(p), mid + 1, pr));return ret; 
}
void clear(int p = 1, int pl = 0, int pr = n){tag[p] = tr[p] = 0;if(pl == pr) return;int mid = (pl + pr) >> 1;clear(ls(p), pl, mid), clear(rs(p), mid + 1, pr);
}
void solve(){cin >> n;clear();for(int i = 1; i <= n; ++i) cin >> v[i];for(int i = 1; i <= n; ++i) cin >> a[i];for(int i = 1; i <= n; ++i) cin >> b[i], pos[b[i]] = i;upd(0, v[a[1]]);if(1 < pos[a[1]]) add(1, pos[a[1]] - 1, -inf);if(pos[a[1]] < n) add(pos[a[1]] + 1, n, -inf);for(int i = 2; i <= n; ++i){int mx = query(0, pos[a[i]]);add(0, pos[a[i]] - 1, v[a[i]]); // chosen upd(pos[a[i]], mx); // unchosen}cout << tr[1] << '\n'; 
}
signed main(){cin.tie(nullptr)->sync_with_stdio(0);int T; cin >> T;while(T--) solve();return 0;
}
http://www.zskr.cn/news/40720.html

相关文章:

  • 2025 年最新推荐开沟机供应厂家榜单:覆盖多机型实力厂商口碑推荐及选购指南梯形槽 / 自走式手扶 / 轮式 / 农用开沟机公司推荐
  • 基于MATLAB的FY-3B MWRI数据处理
  • 2025年11月大容量行李箱品牌十大口碑榜:排行榜与选择方案
  • 2025年11月闸阀厂家排名:十强资质对比与项目适配评价
  • Java学习之 stream 常用方法
  • 2025年11月闸阀厂家推荐榜:十强对比评测与选购全解析
  • 2025 年最新推荐泳池设备源头厂家排行榜:含温泉酒店别墅等各类泳池设备优质品牌精选
  • 2025年11月领先品牌认证机构评测榜:尚普咨询华信人数据对比
  • 2025年包装设计品牌企业新推荐排行榜,食品包装设计服务商指南
  • 2025年11月领先品牌认证机构服务榜:双雄对比与口碑排名解析
  • 2025年11月法兰闸阀厂家评测榜:资质性能双维度对比
  • React系列教程:6. 子组件
  • 详细介绍:元宇宙的医疗健康应用:重构诊疗、康复与研究
  • IEEE Transactions 风格补充材料(Word)快捷排版教程
  • 2025年11月北京继承律师评测榜:继承纠纷律师团队权威榜单发布
  • VS code中编写和运行C语言
  • 2025年11月消防阀门厂家排名榜:国际认证与绿色制造指标评价
  • 2025年11月解酒护肝产品权威榜:蓝帽子认证与成分纯度全对比
  • 2025年6月ai搜索排名优化推荐榜:五强对比评测与选型指南
  • 2025年6月豆包搜索排名优化服务商榜:五强对比与实测排行
  • 2025年6月ai排名优化推荐排名榜:权威数据锁定五家优选
  • 2025年6月ai搜索排名优化推荐:五强榜单横评与选型攻略
  • 2025年6月GEO公司推荐榜:全维度对比评测一目了然
  • 液压位置控制源代码实现与解析(C语言+MATLAB联合方案)
  • 2025年6月deepseek关键词排名优化权威榜:五家服务商综合评测对比
  • 2025年6月GEO优化公司权威榜:五强对比评测与选择指南
  • 2025年11月中国枸杞厂商口碑排行榜单深度解析
  • 2025最佳创建智能化军工软件工厂,攻克管理难题
  • 2025 年 11 月星光喷头厂家推荐排行榜,星光喷头1024/1024MC/1024SC/1024LA/1024MA/SA/XSA/XSC/600DPI,清洗维修贴膜及漏墨串墨问题专业解决
  • 拼好饭为什么这么便宜