ABC343

1|0基本情况

前四题秒了,但是都有不够优雅的地方

F知道是线段树,但是写不出来,极其绝望

2|0C - 343

C - 343 (atcoder.jp)

更简洁的回文判断

2|1MyCode

bool check_p(i64 x) { std::string s(std::to_string(x)); int n = sz(s); for (int i = 0; i < n / 2; i++) { if (s[i] != s[n - i - 1]) return false; } return true; } signed main(){ constexpr int N(1E6 + 10); std::cin >> n; i64 ans(1); for (i64 i = 0; i < N; i++) { i64 num = i * i * i; if (num > n) {std::cout << ans << '\n'; return 0;} if (check_p(num)) ans = num; } std::cout << ans << '\n'; return 0; }

2|2STD

int main() { i64 N; std::cin >> N; i64 ans = 0; for (i64 a = 1; a * a * a <= N; a++) { std::string s = std::to_string(a * a * a); if (s == std::string(s.rbegin(), s.rend())) {//更简洁的回文判断 ans = a * a * a; } } std::cout << ans << "\n"; return 0; }

3|0D - Diversity of Scores

D - Diversity of Scores (atcoder.jp)

不知道map可以erase导致的

3|1MyCode

signed main(){ int N, T; std::cin >> N >> T; std::vector<i64> a(N); std::set<i64> S(all(a)); std::map<i64, int> cnt; cnt[0] = N; for (int _ = 1; _ <= T; _++) { int idx; i64 add; std::cin >> idx >> add; idx--; if (cnt.count(a[idx])) { cnt[a[idx]]--; if (cnt[a[idx]] == 0) { S.erase(a[idx]); } } a[idx] += add; cnt[a[idx]]++; S.insert(a[idx]); std::cout << sz(S) << '\n'; } return 0; }

3|2STD

signed main(){ int N, T; std::cin >> N >> T; std::vector<i64> a(N); std::map<i64, int> cnt; cnt[0] = N; for (int _ = 1; _ <= T; _++) { int idx; i64 add; std::cin >> idx >> add; idx--; if (--cnt[a[idx]] == 0) cnt.erase(a[idx]);//直接用map执行删除操作就行 a[idx] += add; cnt[a[idx]]++; std::cout << sz(cnt) << '\n'; } return 0; }

4|0F - Second Largest Query

F - Second Largest Query (atcoder.jp)

线段树掌握不到位

这里只需要维护次大值,并不需要主席树

而且也不需要通过map等暴力统计次大值数量,可以优雅地直接用线段树在合并时维护

#include <bits/stdc++.h> using i64 = long long; template<class Info> struct SegmentTree { int n; std::vector<Info> info; SegmentTree() : n(0) {} SegmentTree(int n_, Info v_ = Info()) { init(n_, v_); } template<class T> SegmentTree(std::vector<T> init_) { init(init_); } void init(int n_, Info v_ = Info()) { init(std::vector(n_, v_)); } template<class T> void init(std::vector<T> init_) { n = init_.size(); info.assign(4 << std::__lg(n), Info()); std::function<void(int, int, int)> build = [&](int p, int l, int r) { if (r - l == 1) { info[p] = init_[l]; return; } int m = (l + r) / 2; build(2 * p, l, m); build(2 * p + 1, m, r); pull(p); }; build(1, 0, n); } void pull(int p) { info[p] = info[2 * p] + info[2 * p + 1]; } void modify(int p, int l, int r, int x, const Info &v) { if (r - l == 1) { info[p] = v; return; } int m = (l + r) / 2; if (x < m) { modify(2 * p, l, m, x, v); } else { modify(2 * p + 1, m, r, x, v); } pull(p); } void modify(int p, const Info &v) { modify(1, 0, n, p, v); } Info rangeQuery(int p, int l, int r, int x, int y) { if (l >= y || r <= x) { return Info(); } if (l >= x && r <= y) { return info[p]; } int m = (l + r) / 2; return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y); } Info rangeQuery(int l, int r) { return rangeQuery(1, 0, n, l, r); } template<class F> int findFirst(int p, int l, int r, int x, int y, F pred) { if (l >= y || r <= x || !pred(info[p])) { return -1; } if (r - l == 1) { return l; } int m = (l + r) / 2; int res = findFirst(2 * p, l, m, x, y, pred); if (res == -1) { res = findFirst(2 * p + 1, m, r, x, y, pred); } return res; } template<class F> int findFirst(int l, int r, F pred) { return findFirst(1, 0, n, l, r, pred); } template<class F> int findLast(int p, int l, int r, int x, int y, F pred) { if (l >= y || r <= x || !pred(info[p])) { return -1; } if (r - l == 1) { return l; } int m = (l + r) / 2; int res = findLast(2 * p + 1, m, r, x, y, pred); if (res == -1) { res = findLast(2 * p, l, m, x, y, pred); } return res; } template<class F> int findLast(int l, int r, F pred) { return findLast(1, 0, n, l, r, pred); } }; struct Info { int max_1 = -1; int cnt_1 = 0; int max_2 = -2; int cnt_2 = 0; }; Info operator+(Info a, Info b) {//区间合并维护次大值和次大值个数 if (a.max_1 == b.max_1) {//如果两个区间最大值相等 if (a.max_2 < b.max_2) { std::swap(a, b); } a.cnt_1 += b.cnt_1; if (a.max_2 == b.max_2) { a.cnt_2 += b.cnt_2; } } else {//如果两个区间最大值不等 if (a.max_1 < b.max_1) {//先把情况变成a最大值最大 std::swap(a, b); } if (b.max_1 > a.max_2) { //如果b的最大值比a的次大值大(此时a的最大值肯定是最大的,所以b的最大值就是次大值) //此时并不用考虑b的次大值,因为该结构要求了次大值严格小于最大值,既然b的最大值已经小于a了,那么b的次大值只能更小 a.max_2 = b.max_1;//维护次大值 a.cnt_2 = b.cnt_1;//显然次大值改变了,所以个数改成b的最大值的个数 } else if (b.max_1 == a.max_2) {//两个都是次大值,就相加 a.cnt_2 += b.cnt_1; } } return a; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int N, Q; std::cin >> N >> Q; std::vector<int> A(N); for (int i = 0; i < N; i++) { std::cin >> A[i]; } SegmentTree<Info> seg(N); for (int i = 0; i < N; i++) { seg.modify(i, {A[i], 1, -1, 0});//单点修改,最大值等于自己,个数为1.没有次大值,所以设成{0, 1} } while(Q--) { int o; std::cin >> o; if (o == 1) { int p, x; std::cin >> p >> x; p--; seg.modify(p, {x, 1, -1, 0}); } else { int l, r; std::cin >> l >> r; l--;//左闭右开 std::cout << seg.rangeQuery(l, r).cnt_2 << '\n'; } } return 0; }

5|0E - 7x7x7

https://atcoder.jp/contests/abc343/tasks/abc343_e

人类智慧枚举

不难得出:

  • 如果三个立方体完全不交,根本没有枚举的意义。
  • 固定第一个顶点,不影响答案

所以枚举剩下两个立方体的顶点,[7,7]

对于求两两相交的总体积,显然是分别求之后再减去三倍(三三相交)的体积。

对于求不相交的总体积,显然是 3×7×7×72×V23×V3

struct Cube { int x, y, z; Cube(){} Cube(int _x, int _y, int _z) : x(_x), y(_y), z(_z){} friend std::ostream& operator<<(std::ostream& os, const Cube& cube) { os << cube.x << ' ' << cube.y << ' ' << cube.z; return os; } }; signed main() { std::cin.tie(nullptr)->sync_with_stdio(false); std::array<int, 3> v; for (auto& x : v) {std::cin >> x;} std::vector<Cube> C(3); C[0] = Cube(0, 0, 0); auto F_2 = [&](Cube& c1, Cube& c2) { int res = 1; res *= std::max(0, std::min(c1.x, c2.x) + 7 - ranges::max(c1.x, c2.x)); res *= std::max(0, std::min(c1.y, c2.y) + 7 - ranges::max(c1.y, c2.y)); res *= std::max(0, std::min(c1.z, c2.z) + 7 - ranges::max(c1.z, c2.z)); return res; }; auto F_3 = [&](Cube& c1, Cube& c2, Cube& c3) { int res = 1; res *= std::max(0, std::min({c1.x, c2.x, c3.x}) + 7 - std::max({c1.x, c2.x, c3.x})); res *= std::max(0, std::min({c1.y, c2.y, c3.y}) + 7 - std::max({c1.y, c2.y, c3.y})); res *= std::max(0, std::min({c1.z, c2.z, c3.z}) + 7 - std::max({c1.z, c2.z, c3.z})); return res; }; L(a1, -7, 7) L(b1, -7, 7) L(c1, -7, 7) L(a2, -7, 7) L(b2, -7, 7) L(c2, -7, 7) { C[1] = Cube(a1, b1, c1); C[2] = Cube(a2, b2, c2); std::array<int, 3> V; V[2] = F_3(C[0], C[1], C[2]); V[1] = F_2(C[0], C[1]) + F_2(C[0], C[2]) + F_2(C[1], C[2]) - V[2] * 3; V[0] = 3 * 7 * 7 * 7 - V[1] * 2 - V[2] * 3; if (v == V) { std::cout << "Yes\n"; for (auto& cube : C) {std::cout << cube << ' ';} return 0; } } std::cout << "No\n"; return 0; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/18049472.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(244)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示