首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >补题A-D Educational Codeforces Round 166 (Rated for Div. 2)

补题A-D Educational Codeforces Round 166 (Rated for Div. 2)

作者头像
WuShF
发布2025-02-19 09:18:20
发布2025-02-19 09:18:20
12400
代码可运行
举报
文章被收录于专栏:笔记分享笔记分享
运行总次数:0
代码可运行

https://codeforces.com/contest/1976

在这里插入图片描述
在这里插入图片描述

A. Verify Password

利ASCII码表特点,字母的二进制值比数字大。

代码语言:javascript
代码运行次数:0
运行
复制
#include <bits/stdc++.h>
using namespace std;
int n;
string s;
void solve() {
    cin >> n >> s;
    for (int i = 1; i < s.size(); i++) {
        if (s[i] < s[i - 1]) {
            cout << "NO" << endl;
            return;
        }
    }
    cout << "YES" << endl;
}

int main() {
    int tt;
    cin >> tt;
    while (tt--) {
        solve();
    }
    return 0;
}

B. Increase/Decrease/Copy

对于前n位,修改abs(a[i] - b[i])次使a[i]变成b[i]是必须的。 对于第n+1位,如果在之前的修改过程中出现过,那么可以直接移过来,操作次数为1。 如果之前没出现过,那么就找一个离b[n+1]最近的。

  • 可以暴力地枚举每个边界值。
代码语言:javascript
代码运行次数:0
运行
复制
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 5;
int n;
int 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];
    ll ans = 0;
    int mn = 1e9;
    for (int i = 1; i <= n; i++) {
        ans += abs(a[i] - b[i]);
        if (min(a[i], b[i]) <= b[n + 1] && b[n + 1] <= max(a[i], b[i]))
            mn = 0;
        mn = min({mn, abs(a[i] - b[n + 1]), abs(b[i] - b[n + 1])});
    }
    cout << ans + mn + 1 << endl;
}

int main() {
    int tt;
    cin >> tt;
    while (tt--) {
        solve();
    }
    return 0;
}

C. Job Interview

一定有:开发多了,或,测试多了。

  • 如果开发多了,那么前n+1才有可能选到开发,剩下的所有人都是测试
  • 如果测试多了,那么前m+1才有可能选到测试,剩下的所有人都是开发

如果开发多了:

  1. 标记前n个开发的下标 a. 如果第i个缺席者在其中,那么第n+1个开发会从测试转为开发 b. 如果第i个缺席者不在其中,无论原先是开发还是测试,他都只能测试
  2. 计算身份转变的贡献变化。
代码语言:javascript
代码运行次数:0
运行
复制
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define ll long long
const int N = 2e5 + 5;
int n, m;
int a[N], b[N];
int good[N];
void solve() {
    cin >> n >> m;
    ll sa = 0, sb = 0;
    for (int i = 1; i <= n + m + 1; i++)
        cin >> a[i], sa += a[i];
    for (int i = 1; i <= n + m + 1; i++)
        cin >> b[i], sb += b[i];
    vector<int> pos[2];
    for (int i = 1; i <= n + m + 1; i++) {
        pos[a[i] < b[i]].push_back(i);
        good[i] = 0;
    }
    ll sa1 = 0, sb1 = 0;
    if (pos[0].size() > n) {
        for (int i = 0; i < n; i++) {
            sa1 += a[pos[0][i]];
            sb1 += b[pos[0][i]];
            good[pos[0][i]] = 1;
        }
        for (int i = 1; i <= n + m + 1; i++) {
            if (!good[i]) {
                cout << sa1 + sb - sb1 - b[i] << ' ';
            } else {
                cout << sa1 - a[i] + a[pos[0][n]] + sb - sb1 - b[pos[0][n]]
                     << ' ';
            }
        }
    } else {
        for (int i = 0; i < m; i++) {
            sa1 += a[pos[1][i]];
            sb1 += b[pos[1][i]];
            good[pos[1][i]] = 1;
        }
        for (int i = 1; i <= n + m + 1; i++) {
            if (!good[i]) {
                cout << sb1 + sa - sa1 - a[i] << ' ';
            } else {
                cout << sb1 - b[i] + b[pos[1][m]] + sa - sa1 - a[pos[1][m]]
                     << ' ';
            }
        }
    }
    cout << endl;
}

int main() {
    IOS;
    int tt;
    cin >> tt;
    while (tt--) {
        solve();
    }
    return 0;
}

D. Invertible Bracket Sequences

扫描线。 把左括号赋值为1,右括号赋值为-1。 前缀和会表现为一个折线图。 如果选择翻转某个区间的左右括号,相当于把折线图向下对折。 向下对折之后,任一点不应小于0

  • 那么对折前的最高点不应超过i*2i为两端点高度。

组合计数采用的是:枚举右端点,统计所有合法左端点。

代码语言:javascript
代码运行次数:0
运行
复制
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define ll long long
const int N = 2e5 + 5;
int n, m;
string s;
int a[N], pre[N];
vector<int> h[N];
struct Node {
    int mx;
} T[N << 2];
Node merge(Node &l, Node &r) { return {max(l.mx, r.mx)}; }
void build(int p, int l, int r) {
    if (l == r) {
        T[p].mx = pre[l];
    } else {
        int mid = l + r >> 1;
        if (l <= mid)
            build(p << 1, l, mid);
        if (mid < r)
            build(p << 1 | 1, mid + 1, r);
        T[p] = merge(T[p << 1], T[p << 1 | 1]);
    }
}
int query(int p, int l, int r, int nl, int nr) {
    if (nl <= l && r <= nr)
        return T[p].mx;
    int mid = l + r >> 1;
    int ans = 0;
    if (nl <= mid)
        ans = max(ans, query(p << 1, l, mid, nl, nr));
    if (mid < nr)
        ans = max(ans, query(p << 1 | 1, mid + 1, r, nl, nr));
    return ans;
}
void solve() {
    cin >> s;
    n = s.size();
    for (int i = 0; i <= n; i++)
        h[i].clear();
    for (int i = 1; i <= n; i++) {
        a[i] = s[i - 1] == '(' ? 1 : -1;
        pre[i] = pre[i - 1] + a[i];
        h[pre[i]].push_back(i);
    }
    ll res = 0;
    build(1, 1, n);
    for (int i = 0; i <= n; i++) {
        int lst = -1;
        for (int j = 0; j + 1 < h[i].size(); j++) {
            int mh = query(1, 1, n, h[i][j], h[i][j + 1]);
            if (mh > i * 2)
                lst = j;
            res += j - lst;
        }
    }
    cout << res << endl;
}

int main() {
    IOS;
    int tt;
    cin >> tt;
    while (tt--) {
        solve();
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • A. Verify Password
  • B. Increase/Decrease/Copy
  • C. Job Interview
  • D. Invertible Bracket Sequences
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档