做完本期以后,最近就不会再发布 AtCoder 的往届比赛了(备战蓝桥杯ing)
补题链接:Here
ABC题都是水题,这里直接跳过
D - Alter Altar
题意:一个R-W串,可以进行两种操作:1. 交换任意两个字符,2. 改变任意一个字符。问最少操作几次,可以使得串中不包含WR?
思路:
可以发现,使用操作 总不劣于操作
的 。最终需要把串变为
R...RW...W的形式,所以先统计R的个数 ,然后统计前
个字符中
R的个数 ,最后的结果就是
。
int main() {ios_base::sync_with_stdio(false), cin.tie(0);int n; string s;cin >> n >> s;int r = 0, rr = 0;for (int i = 0; i < s.size(); ++i)if (s[i] == 'R') r++;for (int i = 0; i < r; ++i)if (s[i] == 'R') rr++;cout << r - rr;return 0;}
E - Logs
有 根木条,每条长为
,最多锯
次 ,问锯完后最长的木条最短有多长(结果进位为整数)。
思路:经典二分。二分查找最后的答案,判断所需要的次数是否超过 次。
// Murabito-B 21/04/09#include <bits/stdc++.h>using namespace std;using ll = long long;int main() {ios_base::sync_with_stdio(false), cin.tie(0);int n, k;cin >> n >> k;vector<ll> a(n);for (ll &x : a) cin >> x;ll l = 1, r = *max_element(a.begin(), a.end());while (l <= r) {ll mid = l + (r - l) / 2;ll ans = 0;for (ll i : a) ans += (i - 1) / mid;if (ans > k) l = mid + 1;elser = mid - 1;}cout << l;return 0;}
F - Range Set Query
给定数组 ,进行
次 询问,每次需要回答
区间内不同数字的个数。
思路:
经典树状数组解法,离线做法是按查询区间右端点排序然后依次处理,过程中用树状数组记录和更新当前状态。同一个数字,只有最后一次出现是有效的。
代码学习自 CP wiki
// Murabito-B 21/04/09#include <bits/stdc++.h>using namespace std;using ll = long long;// 树状数组类template <class T>class FenwickTree {int limit;vector<T> arr;T lowbit(T x) { return x & (-x); }public:FenwickTree(int limit) {this->limit = limit;arr = vector<T>(limit + 1);}void update(int idx, T val) {for (; idx <= limit; idx += lowbit(idx)) arr[idx] += val;}T query(int idx) {T ans = 0;for (; idx > 0; idx -= lowbit(idx)) ans += arr[idx];return ans;}};int main() {ios_base::sync_with_stdio(false), cin.tie(0);int n, q;cin >> n >> q;vector<int> a(n + 1);for (int i = 1; i <= n; ++i) cin >> a[i];vector<pair<int, int>> Q;for (int i = 0, l, r; i < q; ++i) {cin >> l >> r;Q.push_back({l, r});}vector<int> order(q);for (int i = 0; i < q; ++i) order[i] = i;sort(order.begin(), order.end(), [&](int i, int j) { return Q[i].second < Q[j].second; });vector<int> ans(q), pos(n + 1);int lst = 0;FenwickTree<int> ft(n);for (int i = 0; i < q; ++i) {int k = order[i];int l = Q[k].first, r = Q[k].second;for (int j = lst + 1; j <= r; ++j) {if (pos[a[j]] != 0)ft.update(pos[a[j]], -1);ft.update(j, 1);pos[a[j]] = j;}ans[k] = ft.query(r) - ft.query(l - 1);lst = r;}for (int i : ans) cout << i << "\n";return 0;}
