您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: