当前位置:   article > 正文

Codeforces Round 965 (Div. 2) ABCE1_codeforces round 965 (div. 2)题解

codeforces round 965 (div. 2)题解

A题:Find K Distinct Points with Fixed Center

题意

给定坐标xc和yc,要求给出k个坐标,使得其中点是给定的坐标

思路

明显地,我们只要从xc和yc向两边“扩散”即可

代码

  1. inline void solve() {
  2. int x, y, k; cin >> x >> y >> k;
  3. vector<int> a, b;
  4. if (k & 1) cout << x << ' ' << y << endl;
  5. for (int i = 1; k - 2 * i >= 0; i ++ ) {
  6. cout << x - i << ' ' << y - i << endl;
  7. cout << x + i << ' ' << y + i << endl;
  8. }
  9. return;
  10. }

B题:Minimize Equal Sum Subarrays

题意

给定一个排列,要求你也构造一个排列。

使得两者在(l,r)上的总和相等的(l,r)对数最少

思路

l取1,r取n的时候,无可避免地,两者会相等。

但是,我们看到样例二

5

1 2 3 4 5

构造

2 3 4 5 1

对于前面4个无论怎么取l和r,我们构造的一定比给定的排列大,因此不可能相等

然后再考虑最后一个

最后一个,当且仅当l取1,r取n的时候可以相等,所以这个构造方法是最优解

代码

  1. inline void solve() {
  2. int n; cin >> n;
  3. for (int i = 1; i <= n; i ++ ) {
  4. int x; cin >> x;
  5. x += 1;
  6. if (x > n) x -= n;
  7. cout << x << " \n"[i == n];
  8. }
  9. return;
  10. }

C题:Perform Operations to Maximize Score

题意

给定一个数组和k次操作次数,每次操作可以使得数组中你选定的元素值加上1.

问对于所有的元素ai,ai和去掉第i位后的数组中位数之和最大的是多少?

思路

可以明确知道的是,当我们用完所有操作次数后

一定是a[n] + a[n/2]取到最大的(已经sort过后)

也就是数组中最大的,和中位数

所以,我们可以分出两种情况

1.不变最大的,让中位数增大

2.变最大的,一直增大最大的

为什么就这两种情况呢?

第一种不过多解释

第二种,如果我们把1~n-1数组中的某个ai变成了最大的,再往上加,贡献能够始终加一,是其他方案中的最优解,因此可以覆盖掉其他的考虑

在第二种情况下,我们只要看其是否能加,加上k和中位数再比较即可(当然是选最大的)

而对于第一种,我们可以二分出最大的中位数

二分过程中,我们看cost和cnt

如果x可以是中位数

那么一定有对于前n-1个元素,一定有n-n/2个元素大于等于x(要包括上中位数),而且cost一定小于等于k

代码

  1. inline void solve() {
  2. ll n, k; cin >> n >> k;
  3. vector<PLL> a(n + 1);
  4. for (int i = 1; i <= n; i ++ ) cin >> a[i].first;
  5. for (int i = 1; i <= n; i ++ ) cin >> a[i].second;
  6. sort(a.begin() + 1, a.end());
  7. function<bool(ll)> check = [&](ll x) {
  8. ll cnt = 0, cost = 0;
  9. for (int i = n - 1; i; i -- ) {
  10. if (a[i].first >= x) cnt += 1;
  11. else if (cnt < (n - n / 2) && a[i].second) cost += x - a[i].first, cnt += 1;
  12. }
  13. return (cnt >= n - n / 2) && cost <= k;
  14. };
  15. ll l = 0, r = 1e9 + 7, ans = 0;
  16. while (l + 1 != r) {
  17. ll mid = l + r >> 1;
  18. if (check(mid)) l = mid;
  19. else r = mid;
  20. }
  21. ans = max(ans, a[n].first + l);
  22. for (int i = n; i; i -- ) {
  23. if (a[i].second) {
  24. swap(a[n], a[i]);
  25. sort(a.begin() + 1, a.end() - 1);
  26. ans = max(ans, a[n].first + k + a[n / 2].first);
  27. break;
  28. }
  29. }
  30. cout << ans << endl;
  31. return;
  32. }

E1:E1. Eliminating Balls With Merging (Easy Version)

题意

(简化)给定一个数组a,每次可以选定i和j,删去两者中小的一个,另一个变成两者之和。

问最后剩下来的最后一个元素的情况有多少种?

 思路

对于i,如果它能够留下来,那么一定能够把其他n-1个元素消灭。

每次我们进行操作,帮i进行扩散,把i旁边所有小于a[i]的给消灭掉

然后更新a[i]的值

这样的时间复杂度一定是够的,如果一开始值是a[i],下一次进行扩散的值就一定大于等于2*a[i]

所以时间复杂度是log级别的,然后看是否可以扩散就看最大值即可,用st表维护

代码

  1. const int maxm = 2e5 + 9;
  2. ll st[maxm][30], a[maxm], lg2[maxm], pre[maxm];
  3. int n, k;
  4. inline void build() {
  5. for (int i = 2; i <= n; i ++ ) lg2[i] = lg2[i >> 1] + 1;
  6. for (int i = 1; i <= n; i ++ ) st[i][0] = a[i];
  7. for (int j = 1; (1 << j) <= n; j ++ ) {
  8. for (int i = 1; i + (1 << j - 1) <= n; i ++ ) {
  9. st[i][j] = max(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
  10. }
  11. }
  12. }
  13. inline int query(int l, int r) {
  14. int s = lg2[r - l + 1];
  15. return max(st[l][s], st[r - (1 << s) + 1][s]);
  16. }
  17. inline void solve() {
  18. cin >> n >> k;
  19. for (int i = 1; i <= n; i ++ ) cin >> a[i], pre[i] = pre[i - 1] + a[i];
  20. build();
  21. int ans = 0;
  22. function<void(int)> work = [&](int x) {
  23. int l = x, r = x;
  24. ll cur = a[x];
  25. while (true) {
  26. int temp1 = l, temp2 = r;
  27. int r1 = n + 1;
  28. while (r + 1 != r1) {
  29. int mid = r + r1 >> 1;
  30. if (query(x, mid) <= cur) r = mid;
  31. else r1 = mid;
  32. }
  33. r1 = 0;
  34. while (r1 + 1 != l) {
  35. int mid = r1 + l >> 1;
  36. if (query(mid, x) <= cur) l = mid;
  37. else r1 = mid;
  38. }
  39. cur = pre[r] - pre[l - 1];
  40. if (l == temp1 && r == temp2) break;
  41. }
  42. if (l == 1 && r == n) ans += 1;
  43. };
  44. for (int i = 1; i <= n; i ++ ) work(i);
  45. cout << ans << endl;
  46. return;
  47. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/1003894
推荐阅读
相关标签
  

闽ICP备14008679号