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

Squarepoint Challenge (Codeforces Round 1055, Div. 1 + Div. 2) A~E

A - Increase or Smash

模拟。

对于每个不是最大值的来说,都会经历一次先置为零然后再加的操作,重复项只计算一次;而最大值不用置为零,所以最开始会有一次。

点击查看代码
#include <bits/stdc++.h>using namespace std;using i64 = long long;void solve() {int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i += 1) {cin >> a[i];}int Max = *max_element(a.begin() + 1, a.end());int cnt[101] {}, ans = 1;for (int i = 1; i <= n; i += 1) {if (a[i] != Max) {if (cnt[a[i]] == 0) {ans += 2;cnt[a[i]] += 1;}}}cout << ans << "\n";}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

B - Catching the Krug

分类讨论。

以下以 \(A\) 代表抓的人,\(B\) 代表被抓的人。因为 \(A\) 可以斜着跑,所以只要 \(B\) 不在和 \(A\)\(x\) 轴或 \(y\) 轴上,\(A\) 都可以一边追的同时通过斜着跑移动到同一轴上,从而使得距离只到四个边界上就能抓住他,而 \(B\) 想要活久一点就只能朝相反方向跑,所以最后答案就是判断 \(B\) 朝与 \(A\) 相反的两个坐标轴跑, \(A\) 到达这两个坐标轴的最大距离。

image

点击查看代码
#include <bits/stdc++.h>using namespace std;using i64 = long long;void solve() {int n, k[2], d[2];cin >> n >> k[0] >> k[1] >> d[0] >> d[1];int ans = 0;for(int x = 0; x <= 1; x += 1) {if(k[x] < d[x]) {ans = max(ans, d[x]);} else if(k[x] > d[x]) {ans = max(ans, n - d[x]);}}cout << ans << "\n";}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

C - Triple Removal

前缀和/线段树。

手玩可以发现的是,如果存在两个相邻 \(0/1\),一定通过每次消耗 \(1\) 的代价可以将该区间全部消完(假设区间 \(0/1\) 个数为 \(3\) 的倍数),比如 \(1\textcolor{red}{00}1\textcolor{red}00101011\rightarrow \textcolor{red}{11}0\textcolor{red}{1}01011 \rightarrow \textcolor{red}{00}1\textcolor{red}011\rightarrow \textcolor{red}{111}\),只有 \(010101..\) 交替的时候需要多一次 \(1\) 的代价,后面就都是按照相邻的消法即可。

可以用前缀和维护存不存在相邻的 \(0/1\),我是直接上线段树了。

点击查看代码
#include <bits/stdc++.h>using namespace std;using i64 = long long;template<class Info>
struct SegmentTree {int n;vector<Info> info;SegmentTree(): n(0) {}SegmentTree(int n_, Info v_ = Info()) {init(n_, v_);}template<class T>SegmentTree(vector<T> init_) {init(init_);}void init(int n_, Info v_ = Info()) {init(vector(n_, v_));}template<class T>void init(vector<T> init_) {n = init_.size();info.assign((4 << __lg(n) + 1) + 10, Info());function<void(int, int, int)> build = [&](int u, int l, int r) {if (l == r) {info[u] = init_[l - 1];return ;}i64 m = (l + r) / 2;build(2 * u, l, m);build(2 * u + 1, m + 1, r);pushup(u);};build(1, 1, n);}void pushup(int u) {info[u] = info[2 * u] + info[2 * u + 1];}void modify(int u, int l, int r, int x, const Info &v) {if (l == r) {info[u] = v;return;}int m = (l + r) / 2;if (x <= m) {modify(2 * u, l, m, x, v);} else {modify(2 * u + 1, m + 1, r, x, v);}pushup(u);}void modify(int u, const Info &v) {modify(1, 1, n, u, v);}Info rangeQuery(int u, int l, int r, int x, int y) {if (l > y || r < x) {return Info();}if (l >= x && r <= y) {return info[u];}int m = (l + r) / 2;return rangeQuery(2 * u, l, m, x, y) + rangeQuery(2 * u + 1, m + 1, r, x, y);}Info rangeQuery(int l, int r) {return rangeQuery(1, 1, n, l, r);}
};struct Info {int cnt[2] {};int val[2] {};bool adj = false;
};Info operator+(const Info &l, const Info &r) {Info res;if(r.cnt[0] + r.cnt[1] == 0) {return l;}if(l.cnt[0] + l.cnt[1] == 0) {return r;}res.cnt[0] = l.cnt[0] + r.cnt[0];res.cnt[1] = l.cnt[1] + r.cnt[1];res.val[0] = l.val[0];res.val[1] = r.val[1];res.adj |= (l.val[1] == r.val[0] || l.adj || r.adj);return res;
}void solve() {int n, q;cin >> n >> q;SegmentTree<Info> seg(n);for(int i = 1; i <= n; i += 1) {int x;cin >> x;seg.modify(i, {1 - x, x, x, x});}while(q --) {int l, r;cin >> l >> r;auto res = seg.rangeQuery(l, r);if(res.cnt[0] % 3 || res.cnt[1] % 3) {cout << "-1\n";continue;}int ans = (r - l + 1) / 3;ans += res.adj != true;cout << ans << "\n";}}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

D. Division Versus Addition

思维,前缀和/线段树。

以下定义三类数,如果 \(a_i=2^k\),定义为 \(A\) 类型;\(a_i=2^k+1\),为 \(B\) 类型;其余为 \(C\) 类型,定义 \(|X|\) 代表 \(X\) 类型的数量。

\(A\) 类型比较好分析,\(+1\) 并不会增加代价,所以对面对 \(A\) 类型下手,跟着操作即可;\(B\) 类型,对面一旦下手,操作必定会增加一次,所以当对面对 \(B\) 类型下手,我也得去对其他 \(B\) 类型下手,尽可能减少对面能下手的数量,由于我是先手,一定尽可能对 \(B\) 先下手;\(C\) 类型,手玩了一下,感觉是一直操作一定会有一次操作后使得 \(a_i = 2^k-1\),这个时候对面操作就会增加一次了。

所以总的代价是 \(ans = \sum_{i=1}^n\lfloor \log_2{a_i}\rfloor + \lfloor\frac{|B|}2\rfloor+|C|\)

也可以前缀和,我还是直接上线段树了。

关于更具体的上下界分析,参考[1]

点击查看代码
#include <bits/stdc++.h>using namespace std;using i64 = long long;template<class Info>
struct SegmentTree {int n;vector<Info> info;SegmentTree(): n(0) {}SegmentTree(int n_, Info v_ = Info()) {init(n_, v_);}template<class T>SegmentTree(vector<T> init_) {init(init_);}void init(int n_, Info v_ = Info()) {init(vector(n_, v_));}template<class T>void init(vector<T> init_) {n = init_.size();info.assign((4 << __lg(n) + 1) + 10, Info());function<void(int, int, int)> build = [&](int u, int l, int r) {if (l == r) {info[u] = init_[l - 1];return ;}i64 m = (l + r) / 2;build(2 * u, l, m);build(2 * u + 1, m + 1, r);pushup(u);};build(1, 1, n);}void pushup(int u) {info[u] = info[2 * u] + info[2 * u + 1];}void modify(int u, int l, int r, int x, const Info &v) {if (l == r) {info[u] = v;return;}int m = (l + r) / 2;if (x <= m) {modify(2 * u, l, m, x, v);} else {modify(2 * u + 1, m + 1, r, x, v);}pushup(u);}void modify(int u, const Info &v) {modify(1, 1, n, u, v);}Info rangeQuery(int u, int l, int r, int x, int y) {if (l > y || r < x) {return Info();}if (l >= x && r <= y) {return info[u];}int m = (l + r) / 2;return rangeQuery(2 * u, l, m, x, y) + rangeQuery(2 * u + 1, m + 1, r, x, y);}Info rangeQuery(int l, int r) {return rangeQuery(1, 1, n, l, r);}
};struct Info {int sum = 0, B = 0;
};Info operator+(const Info &l, const Info &r) {return {l.sum + r.sum + (l.B + r.B == 2), (l.B + r.B) % 2};
}void solve() {int n, q;cin >> n >> q;SegmentTree<Info> seg(n + 1);for(int i = 1; i <= n; i += 1) {int x;cin >> x;int k = 0;while((1 << k + 1) <= x) {k += 1;}int y = x - 1;bool B = (y == (y & -y)) && (x & 1);seg.modify(i, {k + ((x != (x & -x)) && !B), B});}while(q --) {int l, r;cin >> l >> r;cout << seg.rangeQuery(l, r).sum << "\n";}}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

E. Monotone Subsequence

明天补下题解


  1. https://codeforces.com/blog/entry/146988 ↩︎

http://www.gsyq.cn/news/16300.html

相关文章:

  • k8s之基础概念
  • 点双连通分量例题:矿场搭建
  • 基于springboot的医护人员排班平台设计与构建(源码+文档+部署讲解)
  • 某中心2026年推出1111个技术实习岗位
  • SQL Indexes(索引) - 详解
  • Payload CMS:开发者优先的Next.js原生开源解决优秀的方案,重新定义无头内容管理
  • python语法记录
  • Go 即时通讯体系:客户端与服务端 WebSocket 通信交互
  • 读混元image论文
  • phone num
  • 当 Python 遇上 Go:Sponge 如何成为替代 Django/Flask 的理想选择 - 指南
  • 2025 年装盒机制造厂 TOP 企业品牌推荐排行榜,自动化 / 喷胶 / 牙膏 / 手机壳 / 3C 数码 / 内外盒 / 面膜 / 电子产品 / 玩具 / 日用品装盒机推荐这十家公司!
  • 英语_阅读_Chinas Spring Festival_待读
  • 2025 权威推荐!电梯源头品牌 TOP5 排行榜:实力厂家精选,品质之选不容错过
  • 2025混合机厂家最新企业品牌推荐排行榜,高效盘条式混合机,无重力混合机,犁刀式混合机,锥形混合机,卧式螺带混合机推荐这十家公司!
  • 在PyCharm中运行 wandb.login();
  • 机器学习科学家分享技术写作艺术
  • AT VP 记录
  • 实用指南:npm run build 报错:Some chunks are larger than 500 KB after minification
  • 关于主体性介枚枚介的讨究
  • 2025索道厂家最新企业品牌推荐排行榜,城市交通索道,旅游索道,滑雪索道,单人固定抱索器拖牵索道,固定抱索器吊篮式索道公司推荐
  • 我终于悟了p1970 花匠
  • 2025 年建筑工程施工总包最新推荐排行榜,以严格质量管控彰显行业实力推荐这十家公司!
  • 平滑技术(数据处理,持续更新...) - 指南
  • 实用指南:本地部署 DeepSeek R1(最新)【从下载、安装、使用和调用一条龙服务】
  • 与斐波那契数列相关的对换题目 CF553B Kyoya and Permutation
  • office办公软件
  • 2025年微信小程序开发:AR/VR与电商的最新案例 - 指南
  • 1 ACwing 271 Mr
  • 实用指南:B站视频下载器 v1.0.4|免登录下载1080P视频