首页 > 其他分享 >20240808

20240808

时间:2024-09-23 11:23:21浏览次数:1  
标签:cnt int sum long Solve tot 20240808

Increase/Decrease/Copy

我们可以先将 \(a_i\) 变为 \(b_i\),统计在变化的过程中与 \(b_{i + 1}\)的最少差值即可

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 2e5 + 5;

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

void Solve() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= n + 1; i++) {
    cin >> b[i];
  }
  int mini = 1e9, ans = 0;
  for (int i = 1; i <= n; i++) {
    if ((a[i] <= b[n + 1] && b[n + 1] <= b[i]) || (b[i] <= b[n + 1] && b[n + 1] <= a[i])) {
      mini = 0;
    }
    mini = min(mini, abs(a[i] - b[n + 1]));
    mini = min(mini, abs(b[i] - b[n + 1]));
    ans += abs(a[i] - b[i]);
  }
  cout << ans + mini + 1 << "\n";
}

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

Job Interview

大模拟,维护 \(4\) 个前缀和然后二分

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 4e5 + 5;

int t, n, m, a[N], b[N], sum[3][N], cnt[3][N], arr[3][N], tot[3], cur;

void Solve() {
  cin >> n >> m;
  for (int i = 1; i <= n + m + 1; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= n + m + 1; i++) {
    cin >> b[i];
  }
  for (int i = 1; i <= n + m + 1; i++) {
    sum[1][i] = sum[1][i - 1] + (a[i] > b[i]) * a[i];
    sum[2][i] = sum[2][i - 1] + (b[i] > a[i]) * b[i];
    cnt[1][i] = cnt[1][i - 1] + (a[i] > b[i]);
    cnt[2][i] = cnt[2][i - 1] + (b[i] > a[i]);
    arr[1][i] = arr[1][i - 1] + a[i];
    arr[2][i] = arr[2][i - 1] + b[i];
  }
  for (int i = 1; i <= n + m + 1; i++) {
    if (i == n + m + 1) {
      cout << cur << "\n";
      break;
    }
    int tmp = n + m + 1;
    for (auto op : {1, 2}) {
      int l = i, r = n + m + 1;
      while (l < r) {
        int mid = (l + r + 1) >> 1;
        if (cnt[op][mid] - cnt[op][i] <= n * (op == 1) + m * (op == 2) - tot[op]) {
          l = mid;
        }
        else r = mid - 1;
      }
     // cout << l << " ";
      tmp = min(tmp, l);
    }
   // cout << "\n";
    int now = sum[1][tmp] - sum[1][i] + sum[2][tmp] - sum[2][i];
    if (cnt[1][tmp] - cnt[1][i] == n - tot[1]) {
      cout << cur + now + arr[2][n + m + 1] - arr[2][tmp] << " ";
    }
    else {
      cout << cur + now + arr[1][n + m + 1] - arr[1][tmp] << " ";
    }
    if (tot[2] == m || (a[i] > b[i] && tot[1] < n)) {
      tot[1]++, cur += a[i];
    }
    else {
     tot[2]++, cur += b[i];
    }
  }
  tot[1] = tot[2] = cur = 0;
}

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

Invertible Bracket Sequences

用一个小根堆,考虑如果当前的和为 \(sum\) 那么之前的 \(sum1 * 2 < sum\) 的都不可以,我们开一个堆,每次统计为\(sum\)有多少个即可

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 4e5 + 5;

int t, n, a[N], ans, cnt[N];

string s;

void Solve() {
  priority_queue<int, vector<int>, greater<int> > q;
  cin >> s;
  n = s.size();
  s = " " + s;
  for (int i = 1; i <= n + 1; i++) {
    cnt[i] = 0;
  }
  cnt[0] = 1;
  ans = 0;
  q.push(0);
  for (int i = 1; i <= n; i++) {
    if (s[i] == '(') {
      a[i] = 1;
    }
    else a[i] = -1;
  }
  for (int i = 1, sum = 0; i <= n; i++) {
    sum += a[i];
    while (!q.empty() && q.top() * 2 < sum) {
      cnt[q.top()]--;
      q.pop();
    }
    ans += cnt[sum];
    q.push(sum);
    cnt[sum]++;
  }
  cout << ans << "\n";
}

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

标签:cnt,int,sum,long,Solve,tot,20240808
From: https://www.cnblogs.com/libohan/p/18426712

相关文章

  • 20240808题解
    话说T2写了个动态树结果考场调不出来,这下大炮打蚊子了。森林(forest)题面:符合条件的森林中深度相同的点度数相同,\(1\lei\len\),求点数为\(i\)的符合条件的森林的种类数。题解:将森林中每一个根节点连到同一个节点上变成一棵树。令\(f(i)\)表示符合条件的树的种类数,那么\(f(i......