补题链接:Here

1535A. Fair Playoff

四名选手参加了季后赛。比赛按以下方案进行:第一名选手与第二名选手比赛,第三名选手与第四名选手比赛,然后两人中的获胜者进入决赛。
众所周知,在两个选手之间的比赛中,技术更高的一个将获胜。第 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图1 位玩家的技能等于 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图2 ,所有技能等级两两不同(i。 e。数组中没有两个相同的值。
如果两位技术最高的选手在决赛中相遇,这场比赛就被称为公平。
确定给定的比赛是否公平。


先进行比较,确定出线玩家的技能值大小,然后排序进行最终比较,如果技能值和相等则输出 YES,否则输出 NO

  1. void solve() {
  2. int a[4];
  3. cin >> a[0] >> a[1] >> a[2] >> a[3];
  4. int b = max(a[0], a[1]), c = max(a[2], a[3]);
  5. sort(a, a + 4);
  6. // cout << b << " " << c << " " << a[0] << " " << a[1] << "\n";
  7. if (a[2] + a[3] == b + c)cout << "YES\n";
  8. else cout << "NO\n";
  9. }

1535B. Array Reodering

好下标数对Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图3 并且 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图4%20%3E%201#card=math&code=gcd%28a_i%2C2a_j%29%20%3E%201&id=IS4T2)

请问在给定的大小为 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图5 的数组可重排序后的最大好下标数对的数量


如果 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图6 的值为偶数,那么 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图7#card=math&code=gcd%28a_i%2C2a_j%29&id=bNYXs) 的值至少为 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图8 并且不必去考虑 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图9 的值,所以我们只需要把原数组的偶数放前面,奇数放后面即可

  1. void solve() {
  2. int n; cin >> n;
  3. vector<int>a, b;
  4. for (int i = 0, x; i < n; ++i) {
  5. cin >> x;
  6. if (x & 1)a.push_back(x);
  7. else b.push_back(x);
  8. }
  9. vector<int>v;
  10. for (int x : b)v.push_back(x);
  11. for (int x : a)v.push_back(x);
  12. int cnt = 0;
  13. for (int i = 0; i < n; ++i)
  14. for (int j = i + 1; j < n; ++j)
  15. if (__gcd(v[i], 2 * v[j] ) > 1)cnt++;
  16. cout << cnt << "\n";
  17. }

更新一发 H神 的写法:Lamda表达式,233ms -> 200ms

  1. void solve() {
  2. int n; cin >> n;
  3. vector<int>a(n);
  4. for (int &x : a)cin >> x;
  5. sort(a.begin(), a.end(), [](const int &x, const int &y) {
  6. return x % 2 < y % 2;
  7. });
  8. int ans = 0;
  9. for (int i = 0; i < n; ++i)
  10. for (int j = i + 1; j < n; ++j)
  11. ans += __gcd(a[i], 2 * a[j]) > 1;
  12. cout << ans << "\n";
  13. }

1535C. Unstable String

给你一个字符串s,定义如果一个字符串任意两个位置符号都不同,且只有0,1组成的字符串是不稳定的。
定义由0,1,?,组成的字符串,且?可以任意的转换成0和1,使字符串可以变成不稳定的字符串叫做美丽字符串。
给一个字符串求有多少子字符串可以形成美丽的字符串。


假如有一个区间 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图10 ,如果这个区间内的字符串是美丽的,那以r结尾的美丽子字符串的贡献就是 r-l+1
我们每次让右指针向右遍历,如果当前区间是美丽字符串,那以 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图11 结尾的子符串产生的贡献就是 r-l+1,如果遍历的过程中当前的字符串不是美丽字符串,那我们就让左指针向右。

但是我们怎么判断当前的区间是不是美丽的呢?

我们判断一个字符串是不是美丽的,其实只需要判断当前区间是不是只有奇数位置上有一种字符,偶数位置上是另一种字符,? 号的时候可以忽略,因为有 ? 可以变成奇数和偶数,不会影响判断。

记得答案要开 long long
因为如果是全是 ? 的串,最终的结果是 Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题) - 图12%2F%202#card=math&code=n%2A%28n%2B1%29%2F%202&id=JZ2Dw) 是会超出 int

  1. void solve() {
  2. string s;
  3. cin >> s;
  4. int type = 0, cnt = 0;
  5. ll ans = 0;
  6. for (int i = 0, j = 0; i < s.size(); ++i) {
  7. while (j < s.size()) {
  8. if (s[j] == '?')j++;
  9. else if (cnt == 0 or type == (s[j] - '0') ^ (j % 2)) {
  10. cnt++;
  11. type = (s[j] - '0') ^ (j % 2);
  12. j++;
  13. } else break;
  14. }
  15. ans += j - i;
  16. if (s[i] != '?')cnt--;
  17. }
  18. cout << ans << "\n";
  19. }

1535D. Playoff Tournament

【题意待补】


代码来自 H神,学习ing….

  1. void solve() {
  2. int k; string s;
  3. cin >> k >> s, s = " " + s;
  4. vector<int>par(1 << k), L(1 << k), R(1 << k), f(1 << k);
  5. for (int i = 1, x = 1, y = (1 << (k - 1)) + 1; i < k; ++i) {
  6. for (int j = 0; j < (1 << (k - i)); ++j) {
  7. par[j + x] = j / 2 + y;
  8. (j & 1 ? R : L)[j / 2 + y] = j + x;
  9. }
  10. x = y;
  11. y += (1 << (k - 1 - i));
  12. }
  13. auto up = [&](int i) {
  14. f[i] = 0;
  15. if (i <= (1 << (k - 1)))f[i] = 1 + (s[i] == '?');
  16. else {
  17. if (s[i] != '1')f[i] += f[L[i]];
  18. if (s[i] != '0')f[i] += f[R[i]];
  19. }
  20. };
  21. for (int i = 1; i < (1 << k); ++i)up(i);
  22. int _; for (cin >> _; _--;) {
  23. int p; string c;
  24. cin >> p >> c;
  25. for (s[p] = c[0] ; p; p = par[p])up(p);
  26. cout << f.back() << "\n";
  27. }
  28. }