Editorial

Revision en9, by Intellegent, 2025-02-16 19:00:38

2064A - Brogramming Contest:

Solution
Code(c++)

2064B - Variety is Discouraged:

Solution
Code(c++)

2064C - Remove the Ends

Solution
Code(c++)

2064D - Eating

Solution
Code(c++)

2064E - Mycraft Sand Sort:

Solution
Code(c++)

2064F - We Be Summing

Solution
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout << #x << " = " << x << "\n";
#define vdebug(a) cout << #a << " = "; for(auto x: a) cout << x << " "; cout << "\n";
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int uid(int a, int b) { return uniform_int_distribution<int>(a, b)(rng); }
ll uld(ll a, ll b) { return uniform_int_distribution<ll>(a, b)(rng); }

template <class T> struct SegTree{
    vector<T> seg;
    int n;
    const T ID = {INT_MAX, -INT_MAX};
    
    T cmb(T a, T b){
        array<int, 2> res;
        res[0] = min(a[0], b[0]);
        res[1] = max(a[1], b[1]);
        return res;
    }
    
    SegTree(int _n){
        n = 1;
        while (n < _n) n *= 2;
        seg.assign(2 * n + 1, ID);
    }
    
    void set(int pos, T val){
        seg[pos + n] = val;
    }
    
    void build(){
        for (int i = n - 1; i >= 1; i--) seg[i] = cmb(seg[2 * i], seg[2 * i + 1]);
    }
    
    void upd(int v, int tl, int tr, int pos, T val){
        if (tl == tr){
            seg[v] = val;
        } else {
            int tm = (tl + tr) / 2;
            if (pos <= tm) upd(2 * v, tl, tm, pos, val);
            else upd(2 * v + 1, tm + 1, tr, pos, val);
            seg[v] = cmb(seg[2 * v], seg[2 * v + 1]);
        }
    }
    
    void upd(int pos, T val){
        upd(1, 0, n - 1, pos, val);
    }
    
    T query(int v, int tl, int tr, int l, int r){
        if (l > r) return ID;
        if (l == tl && r == tr) return seg[v];
        int tm = (tl + tr) / 2;
        T res = query(2 * v, tl, tm, l, min(tm, r));
        res = cmb(res, query(2 * v + 1, tm + 1, tr, max(l, tm + 1), r));
        return res;
    }
    
    T query(int l, int r){
        return query(1, 0, n - 1, l, r);
    }
};

void solve(){
    int n, k;
    cin >> n >> k;

    vector<int> a(n);
    for (int &x : a) cin >> x;

    vector<vector<int>> p(n + 1);
    for (int i = 0; i < n; i++)
        p[a[i]].push_back(i);
    
    vector<array<int, 2>> stk;
    vector<int> small_l(n, -1), small_r(n, n), big_l(n, -1), big_r(n, n);

    for (int i = 0; i < n; i++){
        while (stk.size() && a[i] <= stk.back()[0])
            stk.pop_back();

        if (stk.size())
            small_l[i] = stk.back()[1];
        stk.push_back({a[i], i});
    }

    stk.clear();
    for (int i = n - 1; i >= 0; i--){
        while (stk.size() && a[i] >= stk.back()[0])
            stk.pop_back();

        if (stk.size())
            big_r[i] = stk.back()[1];
        stk.push_back({a[i], i});
    }

    ll ans = 0;
    SegTree<array<int, 2>> seg_small(n), seg_big(n);

    for (int x = 1; x <= n; x++){
        int y = k - x;
        if (y > n){
            for (int pos : p[x])
                seg_small.upd(pos, {pos, pos});
            continue;
        }

        vector<int> pre(p[y].size());
        for (int i = 0; i < p[y].size(); i++){
            if (i > 0)
                pre[i] += pre[i - 1];

            int r = big_r[p[y][i]] - 1;
            if (i < p[y].size() - 1)
                r = min(r, p[y][i + 1] - 1);
            pre[i] += r - p[y][i] + 1;
        }

        vector<int> first(p[x].size()), last(p[y].size());
        for (int i = 0; i < p[x].size(); i++)
            first[i] = seg_small.query(p[x][i], n - 1)[0];

        for (int i = 0; i < p[y].size(); i++)
            last[i] = seg_big.query(0, p[y][i])[1];

        int prev = -1;
        for (int i = 0; i < p[x].size(); i++){
            int l = p[x][i];
            int l_min = small_l[l] + 1;
            l_min = max(l_min, prev + 1);
            prev = l;

            int nxt = upper_bound(p[y].begin(), p[y].end(), l) - p[y].begin();
            if (nxt == p[y].size())
                continue;
       
            int lo = nxt, hi = p[y].size();
            while (lo < hi){
                int mid = (lo + hi) / 2;

                int pos = p[y][mid];
                if (first[i] <= last[mid])
                    hi = mid;
                else
                    lo = mid + 1;
            }

            lo--;
            if (lo < nxt)
                continue;

            int res = pre[lo];
            if (nxt > 0)
                res -= pre[nxt - 1];

            ans += 1LL * (l - l_min + 1) * res;
        }

        for (int pos : p[x])
            seg_small.upd(pos, {pos, pos});
        for (int pos : p[y])
            seg_big.upd(pos, {pos, pos});
    }

    cout << ans << "\n";
}

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

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en19 English Intellegent 2025-02-17 19:42:44 622
en18 English Intellegent 2025-02-17 05:07:46 2 Tiny change: ' contain $0$s, so aft' -> ' contain $1$s, so aft'
en17 English Intellegent 2025-02-16 23:20:53 12
en16 English Intellegent 2025-02-16 19:49:04 12
en15 English Intellegent 2025-02-16 19:40:12 0 (published)
en14 English Intellegent 2025-02-16 19:40:06 41 Tiny change: '[problem:2' -> 'Thank you everyone for participating!\n\n[problem:2' (saved to drafts)
en13 English Intellegent 2025-02-16 19:39:04 13
en12 English Intellegent 2025-02-16 19:36:23 24
en11 English Intellegent 2025-02-16 19:35:26 0 (published)
en10 English Intellegent 2025-02-16 19:20:46 1955 Tiny change: 'oiler>\n\n\n~~~~~\' -> 'oiler>\n\n<spoiler summary="Code(c++)">\n\n~~~~~\'
en9 English Intellegent 2025-02-16 19:00:38 50
en8 English Intellegent 2025-02-16 18:59:57 13106
en7 English Intellegent 2025-02-16 18:55:04 6509
en6 English Intellegent 2025-02-16 17:16:16 1905
en5 English Intellegent 2025-02-15 18:50:10 1910 Tiny change: '{pre}_i_j$$\n</spoil' -> '{pre}_i_j$\n</spoil'
en4 English Intellegent 2025-02-15 18:19:36 951 Tiny change: 'ill cause |a| to decrea' -> 'ill cause $|a|$ to decrea'
en3 English Intellegent 2025-01-28 02:15:22 2182
en2 English Intellegent 2025-01-28 01:39:06 1057
en1 English Intellegent 2025-01-28 01:14:14 58 Initial revision (saved to drafts)