11.23 週六

move_quiet發表於2024-11-24

codeforces
Q1.1200 將一個序列分為若干集合,每個集合的和在一個區間內,問集合數量的最大值。
Q2.1400 長度為n的陣列產生n-2個相鄰三元組,問恰有1個元素不同的三元組的配對數。
Q3.1500 給定n個陣列,設f(x)=max{任意次將x放入任意陣列:x=mex{x,a[i]}},問f(0)+...+f(m)。(m<=1e9)

A1.字首+二分:對於每個數作為起點二分找到滿足條件的最左側的數 細節較多。
雙指標貪心 設s為維護的區間和 s<lim_l r++; s>lim_r l++。
A2.map+容斥:cnt_ab+cnt_ac+cnt_bc-3*cnt_abc 。
A3.結論:計算出每個陣列的x1,x2關鍵點,設max_w=max(x1,x2),發現f(i)為max(i,max_w)。

牛客小白105
C.大力討論,寫了一個小時掛了4發,應該一開始想一個好寫的方法再動鍵盤的(早點重寫的)。
D.並查集板題
E.括號匹配+反向答案:res[i]=n-棧裡元素個數 / 也可生成一棵樹

A1.

#include <bits/stdc++.h>
#define int long long //
#define endl '\n'     //
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
const int mod = 998244353;
const int N = 10 + 5e5;
void _();
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
        _();
    return 0;
}

void _()
{
    int n, L, R;
    cin >> n >> L >> R;
    vector<int> a(n + 1), pre(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i], pre[i] = pre[i - 1] + a[i];
    int res = 0;
    for (int st = 1; st <= n; st++)
    {
        if (a[st] > R)
            continue;
        if (a[st] >= L)
        {
            res++;
            continue;
        }
        int l = st, r = n + 1;
        while (r - l - 1)
        {
            int mid = l + r >> 1;
            if (pre[mid] - pre[st - 1] >= L)
                r = mid;
            else
                l = mid;
        }
        if (r > n)
            continue;
        if (pre[r] - pre[st - 1] > R)
            continue;
        // bug2(st, r);
        res++;
        st = r;
    }
    cout << res << endl;
}

A2.

#include <bits/stdc++.h>
#define int long long //
#define endl '\n'     //
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
const int mod = 998244353;
const int N = 10 + 5e5;
void _();
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
        _();
    return 0;
}

void _()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    map<pair<int, int>, int> cnt_ab, cnt_ac, cnt_bc;
    map<tuple<int, int, int>, int> cnt_abc;
    int res = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (i < 3)
            continue;
        res += cnt_ab[{a[i - 2], a[i - 1]}];
        res += cnt_ac[{a[i - 2], a[i]}];
        res += cnt_bc[{a[i - 1], a[i]}];
        res -= 3 * cnt_abc[{a[i - 2], a[i - 1], a[i]}];
        cnt_ab[{a[i - 2], a[i - 1]}]++;
        cnt_ac[{a[i - 2], a[i]}]++;
        cnt_bc[{a[i - 1], a[i]}]++;
        cnt_abc[{a[i - 2], a[i - 1], a[i]}]++;
    }
    cout << res << endl;
}

A3.

#include <bits/stdc++.h>
#define int long long //
#define endl '\n'     // 互動/除錯 關
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
const int mod = 998244353;
const int N = 10 + 5e5;
void _();
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
        _();
    return 0;
}

void _()
{
    int n, m;
    cin >> n >> m;
    int max_w = 0;
    for (int i = 0; i < n; i++)
    {
        int k;
        cin >> k;
        map<int, bool> has;
        while (k--)
        {
            int x;
            cin >> x;
            has[x] = 1;
        }
        int find = 0;
        for (int h = 0;; h++)
            if (!has[h])
            {
                max_w = max(max_w, h);
                find++;
                if (find == 2)
                    break;
            }
    }
    // bug(max_w);
    int res = (m + 1) * max_w;
    if (m > max_w)
        res = (max_w + 1) * max_w + (max_w + 1 + m) * (m - max_w) / 2;
    cout << res << endl;
}

相關文章