20240913

libohan0518發表於2024-09-27

Red Pandaships

我們會發現如果有奇數個熊貓被夾在兩個熊貓之間,那麼一定會相交

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 3e5 + 5;

int t, n, m;

void Solve(){
  cin >> n >> m;
  int ans = 0;
  for (int i = 1, u, v; i <= m; i++) {
    cin >> u >> v;
    if (abs(u - v + 1) % 2 == 1) {
      ans++;
    }
  }
  cout << ans << "\n";
}

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> t;
  while (t--) {
    Solve();
  }
  return 0;
}

Red Pandacakes

我們會發現,這個值表示成函式就是一個單峰函式,所以二分即可

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 4e5 + 5;

int t, n, a[N], sum[N];

int getans(int l, int r) {
  return sum[r] - sum[l - 1];
}

void Solve() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    a[i + n] = a[i];
  }
  for (int i = 1; i <= 2 * n; i++) {
    sum[i] = sum[i - 1] + a[i];
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int l = i, r = n + i + 1;
    while (l < r) {
      int mid = (l + r + 1) >> 1;
      if (getans(i, mid) <= getans(mid, i + n)) {
        l = mid;
      }
      else r = mid - 1;
    }
    int tmp1 = max(getans(i, l) - a[l], getans(l, i + n) - a[l]);
    int tmp2 = max(getans(i, l + 1) - a[l + 1], getans(l + 1, i + n) - a[l + 1]);
    ans = max(ans, min(tmp1, tmp2));
  }
  cout << ans << '\n';
}

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> t;
  while (t--) {
    Solve();
  }
  return 0;
}

Range Flips

我們可以手推一下變化規律,我們會發現他的值一定是 \(x, 25 - x, 13 + x, 12 - x\) 所以我們設 \(dp_{i, 0/1, 0/1}\) 表示當前考慮至第幾個,有沒有做一操作,有沒有做二操作

#include <bits/stdc++.h>

using namespace std;

using Pii = pair<int, int>;

#define int long long

const int N = 1e6 + 5, INF = 1e18;

int n, dp[N][2][2], s[N], t[N];

string _s, _t;

vector<Pii> a[N];

signed main() {
  cin >> n >> _s >> _t;
  _s = " " + _s, _t = " " + _t;
  for (int i = 1; i <= n; i++) {
    s[i] = (int)(_s[i] - 'a');
    t[i] = (int)(_t[i] - 'a');
    if (s[i] == t[i]) {
      a[i].push_back({0, 0});
    }
    if (25 - s[i] == t[i]) {
      a[i].push_back({1, 0});
    }
    if ((13 + s[i]) % 26 == t[i]) {
      a[i].push_back({0, 1});
    }
    if ((38 - s[i]) % 26 == t[i]) {
      a[i].push_back({1, 1});
    }
    if (s[i] != t[i] && 25 - s[i] != t[i] && (13 + s[i]) % 26 != t[i] && (38 - s[i]) % 26 != t[i]) {
      cout << "-1";
      return 0;
    }
  }
  for (int i = 0; i <= n; i++) {
    for (auto a : {0, 1}) {
      for (auto b : {0, 1}) {
        dp[i][a][b] = INF;
      }
    }
  }
  dp[0][0][0] = 0;
  for (int i = 1; i <= n; i++) {
    for (auto _a : {0, 1}) {
      for (auto _b : {0, 1}) {
        for (auto cur : a[i]) {
          int x = cur.first, y = cur.second;
          int tmp = 0;
          if (_a == 0 && _a != x) {
            tmp++;
          }
          if (_b == 0 && _b != y) {
            tmp++;
          }
          dp[i][x][y] = min(dp[i][x][y], dp[i - 1][_a][_b] + tmp);
        }
      }
    }
  }
  cout << min({dp[n][0][0], dp[n][0][1], dp[n][1][0], dp[n][1][1]});
  return 0;
}
/*
a ------ 25 - a
|           |
|           |
|           |
13 + a---12 - a
*/
/*
 0  0  0  0  0
25 13 12 13 12
 1  0  1  0  1
 0  1  1  1  1
*/