2021暑假模拟赛6

A[ABC172B(20)]

计算多少个对应的位置不同即可。

#include <bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string s, t;
    cin >> s >> t;

    int ans = 0;
    for(int i = 0; i < s.size(); ++i) {
        ans += (s[i] != t[i]);
    }

    cout << ans << '\n';

    return 0;
}
View Code

B[HDU6986(1500)]

考虑一个常见维护不同颜色数的套路,开一个桶,如果一个颜色第一次加进来那么总数加$1$,如果颜色删没了总数减$1$,然后每次$dfs$维护这个桶即可。

#include <bits/stdc++.h>
using namespace std;
const int P1 = 1e9 + 7;
const int P2 = 1e9 + 9;
const int seed = 19560929;
int main() {
  int T;
  scanf("%d", &T);
  while (T --> 0) {
    int N;
    scanf("%d", &N);
    vector<vector<int>> adj(N);
    for (int i = 1; i < N; ++i) {
      int P;
      scanf("%d", &P);
      P --;
      adj[P].push_back(i);
      adj[i].push_back(P);
    } 
    vector<int> C(N);
    for (int i = 0; i < N; ++i) {
      scanf("%d", &C[i]);
      C[i] --;
    }
    vector<long long> pw1(N + 1);
    vector<long long> pw2(N + 1);
    pw1[0] = 1;
    pw2[0] = 1;
    for (int i = 0; i < N; ++i) {
      pw1[i + 1] = pw1[i] * seed % P1; 
      pw2[i + 1] = pw2[i] * seed % P2;
    }
    long long Ans1 = 0;
    long long Ans2 = 0;
    vector<int> cnt(N);
    int tot = 0;
    auto dfs = [&] (auto &&f, int X, int F) -> void {
      cnt[C[X]] ++;
      if (cnt[C[X]] == 1) {
        tot ++;
      }
      Ans1 += 1LL * tot * pw1[X];
      Ans1 %= P1;
      Ans2 += 1LL * tot * pw2[X];
      Ans2 %= P2;
      for (int Y : adj[X]) {
        if (Y != F) {
          f(f, Y, X);
        }
      } 
      cnt[C[X]] --;
      if (cnt[C[X]] == 0) {
        tot --;
      }
    };
    for (int S = 0; S < N; ++S) {
      Ans1 = 0;
      Ans2 = 0;
      dfs(dfs, S, -1);
      printf("%lld %lld\n", Ans1, Ans2);
    }
  }
}
View Code

C[CF1554D(1800)]

需要一个观察,观察出长为$n$的全$a$串和长度为$n+1$的全$a$串连起来是可行的,那么分类讨论中间需要接几个字符即可。

#include <bits/stdc++.h>
using namespace std;
int main() {
  int T;
  cin >> T;
  while (T --> 0) {
    int N;
    cin >> N;
    if (N == 1) {
      cout << 'a' << '\n';
      continue;
    }
    if (N % 2 == 0) {
      int X = (N - 1) / 2; 
      int Y = N - 1 - X;
      string Ans = "";
      for (int i = 0; i < X; ++i) {
        Ans += 'a';
      }
      Ans += 'b';
      for (int i = 0; i < Y; ++i) {
        Ans += 'a';
      }
      cout << Ans << '\n';
    } else {
      int X = (N - 2) / 2; 
      int Y = N - 2 - X;
      string Ans = "";
      for (int i = 0; i < X; ++i) {
        Ans += 'a';
      }
      Ans += 'b';
      Ans += 'c';
      for (int i = 0; i < Y; ++i) {
        Ans += 'a';
      }
      cout << Ans << '\n';
    }
  }
}
View Code

D[CF1156C(2000)]

思考一下容易得出几个性质:答案不超过$\frac{n}{2}$,并且选择区间左端点肯定尽量靠左好。那么问题简单了,左端点肯定是左边连续的一段,右端点肯定是右边连续的一段,于是利用单调性求出答案即可。

#include <bits/stdc++.h>
using namespace std;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, z;
  cin >> n >> z;
  vector<int> x(n);
  for (int i = 0; i < n; ++i) {
    cin >> x[i];
  }
  sort(x.begin(), x.end());
  int l = -1;
  int r = n / 2 + 1;
  while (r - l > 1) {
    int mid = l + r >> 1;
    bool ok = true;
    for (int i = 0, j = mid; i < mid; ++i) {
      while (j < n && x[j] - x[i] < z) {
        j ++;
      } 
      if (j == n) {
        ok = false;
        break;
      }
      j ++;
    }
    if (ok) {
      l = mid;
    } else {
      r = mid;
    }
  }
  cout << l << '\n';
}
View Code

 

posted @ 2021-08-04 20:51  19992147  阅读(62)  评论(0编辑  收藏  举报