ABC343
1|0基本情况
前四题秒了,但是都有不够优雅的地方
F知道是线段树,但是写不出来,极其绝望
2|0C - 343
更简洁的回文判断
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
人类智慧枚举
不难得出:
- 如果三个立方体完全不交,根本没有枚举的意义。
- 固定第一个顶点,不影响答案
所以枚举剩下两个立方体的顶点,
对于求两两相交的总体积,显然是分别求之后再减去三倍(三三相交)的体积。
对于求不相交的总体积,显然是
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 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/kdlyh/p/18049472.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示