Codeforces Round 969 (Div. 2) A- D 题解
Codeforces Round 969 (Div. 2)
A - Dora's Set
Question
集合
Solution
考虑
所以只需要模拟删除过程就好了
Code
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen ("A.in", "r", stdin);
int T; cin >> T;
while (T--) {
int l, r; cin >> l >> r;
if (l % 2 == 0) l += 1;
if (r % 2 == 1) r += 1;
int len = r - l + 1;
cout << len / 4 << '\n';
}
return 0;
}
B - Index and Maximum Value
Question
在她的生日派对上收到了另一个整数数组
具体来说,她将按顺序执行
。 给定两个整数 和 ,对于所有 ,满足 ,将 。 。 给定两个整数 和 ,对于所有 ,满足 ,将 。
Index 对数组
Solution
如果此次的最大值为
Code
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen ("B.in", "r", stdin);
int T; cin >> T;
while (T--) {
int n, m; cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
int m_ = *max_element(a.begin(), a.end());
while (m--) {
char op; cin >> op;
int l, r; cin >> l >> r;
if (op == '+' && l <= m_ && m_ <= r) m_ += 1;
else if (op == '-' && l <= m_ && m_ <= r) m_ -= 1;
cout << m_ << ' ';
}
cout << '\n';
}
return 0;
}
C - Dora and C++
Question
给定一个序列,可以给单点
Solution
根据裴蜀定理,
对序列排序去重后的序列为
Code
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int main() {
freopen ("C.in", "r", stdin);
ios::sync_with_stdio(0); cin.tie(0);
int T; cin >> T;
while (T--) {
int n, a, b; cin >> n >> a >> b;
int g = __gcd(a, b);
vector<int> c(n + 1);
for (int i = 1; i <= n; i++) cin >> c[i];
for (int i = 1; i <= n; i++) c[i] = c[i] % g;
auto c_ = c;
sort(c_.begin() + 1, c_.end());
c_.erase(unique(c_.begin() + 1, c_.end()), c_.end());
int m = c_.size() - 1;
int ans = INF;
for (int i = 1; i <= m; i++) {
int pre = (i == 1) ? m : i - 1;
int now = (c_[pre] - c_[i] + g) % g;
ans = min(ans, now);
}
cout << ans << '\n';
}
return 0;
}
D - Iris and Game on Tree
Question
Iris 有一棵以
我们考虑树的一个叶子节点(顶点
以下面这棵树为例。绿色的顶点值为
- 计算叶子节点
的权值:构造出的字符串为 。其中, 的出现次数为 , 的出现次数为 ,所以它们的数量之差为 。 - 计算叶子节点
的权值:构造出的字符串为 。其中, 的出现次数为 , 的出现次数为 ,所以它们的数量之差为 。
树的得分定义为树中权值不为零的叶子节点数。
但是,一些顶点的值尚未确定,将以
假设两个女孩都采取最优策略,请确定树的最终得分。
Solution
先考虑什么字符串能让树的得分增加,手玩几组就会发现 01 子串和 10 子串数量不同,等价于第一个和第二个字母是否相同,对应到图中就是根节点的权值和叶子节点的权值
如果根节点的权值已经确定了,那么他们肯定优先去修改叶子节点
如果根节点的权值是 ?,那么就要分类讨论了
- 如果叶子节点
的个数多,那么根节点选 - 如果叶子节点
的个数多,那么根节点选 - 如果叶子节点
数量一样多,那么先手去修改根节点的人比吃亏,所以去取非根非叶子节点,非根非叶子节点取完后再取根节点,所以谁先手去修改根节点取决于非根非叶子节点的奇偶性
Code
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen ("D.in", "r", stdin);
int T; cin >> T;
while (T--) {
int n; cin >> n;
vector<int> du(n + 1, 0);
vector<vector<int>> g(n + 1);
int ans = 0;
int cnt_leaf = 0, cnt_other = 0;
int leaf_0 = 0, leaf_1 = 0;
for (int i = 1; i < n; i++) {
int u, v; cin >> u >> v;
du[u] += 1, du[v] += 1;
g[u].push_back(v); g[v].push_back(u);
}
string s; cin >> s; s = " " + s;
for (int i = 1; i <= n; i++) {
if (i == 1) continue;
if (du[i] == 1) {
if (s[i] == '?') cnt_leaf += 1;
if (s[i] == '0') leaf_0 += 1;
if (s[i] == '1') leaf_1 += 1;
}
else {
if (s[i] == '?') cnt_other += 1;
}
}
int cnt = cnt_leaf + cnt_other + (s[1] == '?');
if (s[1] == '?') {
if (leaf_0 > leaf_1) {
ans += leaf_0;
ans += cnt_leaf / 2;
}
else if (leaf_0 < leaf_1) {
ans += leaf_1;
ans += cnt_leaf / 2;
}
else {
if (cnt_other % 2 == 0) {
ans += cnt_leaf / 2;
ans += leaf_0;
}
else {
ans += (cnt_leaf + 1) / 2;
ans += leaf_0;
}
}
}
else {
if (s[1] == '0')
ans += leaf_1;
else
ans += leaf_0;
ans += (cnt_leaf + 1) / 2;
}
cout << ans << '\n';
}
return 0;
}