AtCoder Beginner Contest 174 个人题解(ABC水题,D思维,E题经典二分,F离线树状数组)
2021-04-09 21:17
204 查看
做完本期以后,最近就不会再发布 AtCoder 的往届比赛了(备战蓝桥杯ing)
补题链接:Here
ABC题都是水题,这里直接跳过
D - Alter Altar
题意:一个
R-
W串,可以进行两种操作:1. 交换任意两个字符,2. 改变任意一个字符。问最少操作几次,可以使得串中不包含
WR?
思路:
可以发现,使用操作 1 总不劣于操作 2 的 。最终需要把串变为
R...RW...W的形式,所以先统计
R的个数 r ,然后统计前 r 个字符中
R的个数 r′ ,最后的结果就是 \Delta r=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
有 N 根木条,每条长为 L_i ,最多锯 K 次 ,问锯完后最长的木条最短有多长(结果进位为整数)。
思路:经典二分。二分查找最后的答案,判断所需要的次数是否超过 K 次。
// 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; else r = mid - 1; } cout << l; return 0; }
F - Range Set Query
给定数组 A,进行 $Q$次 询问,每次需要回答 $[L_i,R_i]$区间内不同数字的个数。
思路:
经典树状数组解法,离线做法是按查询区间右端点排序然后依次处理,过程中用树状数组记录和更新当前状态。同一个数字,只有最后一次出现是有效的。
代码学习自 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; }
相关文章推荐
- Codeforces 387E George and Cards【思维+RMQ+二分+树状数组】被卡常= =
- AtCoder Regular Contest 068 E - Snuke Line 离线+树状数组
- AtCoder Beginner Contest 050 ABC题
- hdu 3333 离线线段树 + 思维/树状数组 /在线主席树
- AtCoder Beginner Contest 073 ABC C++&&Python3
- 2013 Asia Regional Contest Problem H --- Number Squence (树状数组 + 离线)
- HDU 4417 Super Mario(离线,线段树/树状数组,思维)
- Wannafly挑战赛3 C.位数差【思维+离散化+二分+树状数组】
- AtCoder Beginner Contest 088 C Takahashi's Information 【思维枚举】
- 【Gym 102134-E】Kth subtree【权值树状数组、二分统计第k大+dfs离线操作】
- AtCoder Beginner Contest 083 - D - Wide Flip(思维)
- 2019 Multi-University Training Contest 3 树状数组上的二分
- AtCoder Beginner Contest 069 ABC C++&&Python
- hdu 5869 RMQ+二分+离线树状数组
- AtCoder Beginner Contest 081 D - Non-decreasing 【思维移位】
- Hrbust 1390 Leyni, LOLI and Numbers【思维+树状数组+二分+双向链表模拟】好题!好题!好题!
- AtCoder Beginner Contest 070 ABC C++&&python
- AtCoder Beginner Contest 174
- Sdut 3252 Lowest Unique Price【思维+二分+树状数组】
- AtCoder Beginner Contest 072 ABCD C++&&Python3