Hướng dẫn cho Summer Contest #02 - Đoạn Domino


Chỉ sử dụng khi thực sự cần thiết như một cách tôn trọng tác giả và người viết hướng dẫn này.

Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.

Authors: ledinhbaonam, uia

Do authors quá lười viết hướng dẫn nên chỉ để code thôi nhé! Thông cảm lần 3, ahihihi~~~

C++
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int nmax = 10005;
int a[nmax];
int st[4 * nmax];
int tc[4 * nmax];
int tl[4 * nmax];
int ms[nmax];
int ns[nmax];

void ps(int id) {
    if (tl[id] != 0) {
        int t = tl[id];
        int l = id << 1;
        int r = l | 1;
        st[l] += t;
        tl[l] += t;
        st[r] += t;
        tl[r] += t;
        tl[id] = 0;
    }
}

void mg(int id) {
    int l = id << 1;
    int r = l | 1;
    int m = min(st[l], st[r]);
    st[id] = m;
    tc[id] = 0;
    if (st[l] == m) tc[id] += tc[l];
    if (st[r] == m) tc[id] += tc[r];
}

void bd(int id, int l, int r) {
    tl[id] = 0;
    if (l == r) {
        st[id] = l;
        tc[id] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    bd(id << 1, l, mid);
    bd((id << 1) | 1, mid + 1, r);
    mg(id);
}

void up(int id, int l, int r, int ql, int qr, int val) {
    if (ql <= l && r <= qr) {
        st[id] += val;
        tl[id] += val;
        return;
    }
    ps(id);
    int mid = (l + r) >> 1;
    if (ql <= mid) up(id << 1, l, mid, ql, qr, val);
    if (qr > mid) up((id << 1) | 1, mid + 1, r, ql, qr, val);
    mg(id);
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    freopen("domino.inp", "r", stdin);
    freopen("domino.out", "w", stdout);
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    while (q--) {
        int t;
        cin >> t;
        if (t == 1) {
            int p, x;
            cin >> p >> x;
            a[p] = x;
        } else {
            int lq, rq;
            cin >> lq >> rq;
            bd(1, lq, rq);
            int mt = 0, nt = 0;
            int ans = 0;
            for (int j = lq; j <= rq; ++j) {
                int l1 = j;
                while (mt > 0 && a[ms[mt - 1]] <= a[j]) {
                    int p = ms[--mt];
                    int lb = (mt == 0) ? lq : max(lq, ms[mt - 1] + 1);
                    up(1, lq, rq, lb, p, -a[p]);
                    l1 = lb;
                }
                up(1, lq, rq, l1, j, a[j]);
                ms[mt++] = j;
                int l2 = j;
                while (nt > 0 && a[ns[nt - 1]] >= a[j]) {
                    int p = ns[--nt];
                    int lb = (nt == 0) ? lq : max(lq, ns[nt - 1] + 1);
                    up(1, lq, rq, lb, p, a[p]);
                    l2 = lb;
                }
                up(1, lq, rq, l2, j, -a[j]);
                ns[nt++] = j;
                if (st[1] == j) {
                    ans += tc[1];
                }
            }
            cout << ans << "\n";
        }
    }
    return 0;
}

Bình luận

Mới nhất
Tải bình luận...

Không có bình luận nào.