Hello 2023 A-D

Hello 2023 A-D

https://codeforces.com/contest/1779
后面的还没看。感觉晚上脑子不好用了qwq

A. Hall of Fame

LR->RL,修改一个即可覆盖全部

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int n;
    string s;
    cin >> n >> s;
    int cnt1 = count (s.begin (), s.end (), 'L'), cnt2 = count (s.begin (), s.end (), 'R');
    if (!cnt1 || !cnt2)     cout << -1 << endl;
    else {
        int cnt = 0, ans = 0; //LR->RL
        for (int i = 1; i < n; i++) {
            if (s[i] == 'R' && s[i-1] == 'L') {
                cnt ++;
                cout << i << endl;
                return ;
            }
        }
        if (cnt) cout << "-1\n";
        else    cout << "0\n";
    }
}

int main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

B. MKnez's ConstructiveForces Task

构造,偶数长度可使总和为 \(0\),奇数长度可使总和为 \(-1\)

\[-1=(\frac n2 + 1)\times(\frac n2 -1) - \frac n2\times\frac n2 \]

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int n;
    cin >> n;
    if (n & 1) {
        if (n == 3)     cout << "NO\n";
        else {
            cout << "YES\n";
            for (int i = 0; i < n / 2; i++)     cout << n / 2 - 1 << ' ' << -1 * n / 2 << ' ';
            cout << n / 2 - 1;
            cout << endl;
        }
    }
    else {
        cout << "YES\n";
        for (int i = 0; i < n / 2; i++)     cout << "1 -1 ";
        cout << endl;
    }
}

int main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

C. Least Prefix Sum

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 2e5 + 5;
int a[N], n, m;

void solve () {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)    cin >> a[i];
    if (n == 1) {
        cout << 0 << endl;
        return ;
    }
    
    //从m往两头出发,小于0就修正
    int ans = 0, sum = 0;
    priority_queue <int, vector<int>, greater<int>> q; //小
    for (int i = m + 1; i <= n; i++) {
        sum += a[i];
        q.push (a[i]);
        if (sum < 0) {
            auto it = q.top ();
            q.pop ();
            ans ++;
            sum += -2 * it;
        }
    }
       
    sum = 0;
    priority_queue<int> p; //大
    for (int i = m; i > 1; i--) {
        sum += a[i];
        p.push (a[i]);
        if (sum > 0) {
            auto it = p.top ();
            p.pop ();
            ans ++;
            sum += -2 * it;
        }
    }

    cout << ans << endl;
}

signed main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

//应该贪心改

D. Boris and His Amazing Haircut

首先刀片只能砍的更小,如果存在 \(b[i]>a[i]\) 则一定不可能。
然后如果想一刀切到长度为 \(x\) 的话,两个端点之间不能有大于 \(x\)\(b_i\).

因此可以记录每个 \(b_i\) 的所在位置,然后两两之间查询有无 \(>b_i\) 的值,若无,则可节省一个刀片。
因为有多次查询,所以可以用ST表记录区间最小值

#include <bits/stdc++.h>

using namespace std;
const int N = 2e5 + 5;
int a[N], b[N], n, m;
int f[N][21], Log2[N];

void pre() {  // 准备工作,初始化
    for (int i = 2; i <= N; ++i)    Log2[i] = Log2[i / 2] + 1;
}

void build() {
    for (int i = 1; i <= n; i++)    f[i][0] = b[i];
    for (int i = 1; i <= 20; ++i) {
        for (int j = 1; j + (1 << i) - 1 <= n; ++j) {
            f[j][i] = max(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);
        }
    }
}

int query(int L, int R) {
    int len = Log2[R - L + 1];
    return max(f[L][len], f[R - (1 << len) + 1][len]);
}

void solve () {
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> a[i];
    for (int i = 1; i <= n; i++)    cin >> b[i];
    build ();
    cin >> m;
    map<int, int> cnt;
    while (m --) {
        int x;  cin >> x;
        cnt[x] ++;
    }
    
    map<int, vector<int>> pos;
    for (int i = 1; i <= n; i++) {
        if (b[i] > a[i]) {
            puts ("NO");
            return ;
        }
        if (b[i] < a[i])    pos[b[i]].push_back (i);
    }

    //for (auto i = s.rbegin (); i != s.rend (); i++)    cout << *i << ": " << L[*i] << ' ' << R[*i] << endl;   cout << endl;
    for (auto pii : pos) {
        vector <int> v = pii.second;
        int cur = pii.first, need = v.size ();
        for (int i = 1; i < v.size (); i++) {
            if (query (v[i-1], v[i]) <= cur)    need --; //省下一个刀片
        }
        if (need > cnt[cur]) {
            puts ("NO");
            return ;
        }
    }
    puts ("YES");
}

int main () {
    ios::sync_with_stdio (0);cin.tie (0);cout.tie (0);
    pre ();
    int t;
    cin >> t;
    while (t --)    solve ();
}

//ST表查找区间最小值
posted @ 2023-01-04 11:53  Sakana~  阅读(51)  评论(0编辑  收藏  举报