CDQ分治求助
查看原帖
CDQ分治求助
569180
Justin0779楼主2024/12/13 12:37

rt,代码莫名其妙的MLE或WA,样例也不到怎么错了一点点,求调(算过了空间应该不会爆,卡的很紧)

#include <bits/stdc++.h>
using namespace std;
constexpr int MAXN = 1e5;
constexpr int MAXM = 1e6;
constexpr int unit = 317;

int n, m;
int A[MAXM + 10], B[MAXM + 10], l[MAXM + 10], ans[MAXM + 10];

struct Element {
    int pre;
    int val;
} e[MAXN + 10];

struct Query {
    int id;
    int r;
} q[MAXM * 2 + 10];


bool ecmp(Element x, Element y) {
    return x.pre < y.pre;
}

bool cmpr(Query x, Query y) {
    if (x.r != y.r) return x.r < y.r;
    return l[x.id] < l[y.id];
}

bool cmpl(Query x, Query y) {
    return l[x.id] < l[y.id];
}

struct BinaryIndexTree {
    int c[MAXN + 10];

    void add(int x, int o) { while (x <= MAXN) c[x] += o, x += x & -x; }
    int qry(int x) { int res = 0; while (x) res += c[x], x -= x & -x; return res; }

    int qry(int l, int r) {
        if (l > r) return 0;
        return qry(r) - qry(l - 1);
    }
};


using bit = BinaryIndexTree;


void CDQ(int L, int R, int LL, int RR, bit &cnt) {
    if (LL > RR || L > R) return ;
    if (L == R) {
        int w;
        for (int i = LL; i <= RR; i++) {
            w = 1;
            if (q[i].r == l[q[i].id]) w = -1;
            ans[q[i].id] += w * (e[L].val >= A[q[i].id] && e[L].val <= B[q[i].id] && e[L].pre <= l[q[i].id] && L <= q[i].r);
        }
        return;
    }

    if (LL == RR) {
        int w;
        w = 1;
        if (q[LL].r == l[q[LL].id]) w = -1;
        for (int i = L; i <= R; i++) 
            ans[q[LL].id] += w * (e[i].val >= A[q[LL].id] && e[i].val <= B[q[LL].id] && e[i].pre <= l[q[LL].id] && i <= q[LL].r);
        return;
    }

    int res = MAXM * 10;
    int i = LL, j = RR, mid = (L + R) / 2;
    while (i <= j) {
        int md = (i + j) / 2;
        if (q[md].r <= mid) res = md, i = md + 1;
        else j = md - 1;
    }

    if (res == MAXM * 10) CDQ(mid + 1, R, LL, RR, cnt);
    else {
        CDQ(L, mid, LL, res, cnt);
        CDQ(mid + 1, R, res + 1, RR, cnt);
    }

    sort(e + L, e + R + 1, ecmp);
    if (res + 1 <= RR) sort(q + res + 1, q + RR + 1, cmpl);

    i = L;
    if (res == MAXM * 10) j = LL;
    else j = res + 1;
    int w;
    while (j <= RR) {
        while (i <= mid && e[i].pre <= l[q[j].id]) cnt.add(e[i].val, 1), i++;
        w = 1;
        if (q[j].r == l[q[j].id]) w = -1;
        ans[q[j].id] += w * cnt.qry(A[q[j].id], B[q[j].id]);
        j++;
    }

    for (int s = L; s < i; s++) cnt.add(e[s].val, -1);
}

int main() {
    cin >> n >> m;
    int *pr = new int[MAXN + 10];
    memset(pr, 0, sizeof pr);
    for (int i = 1; i <= n; i++) {
        cin >> e[i].val;
        e[i].pre = pr[e[i].val];
        pr[e[i].val] = i;
    }

    delete []pr;
    pr = nullptr;

    for (int i = 1, ll, rr, a, b; i <= m; i++) {
        cin >> ll >> rr >> a >> b;
        q[i * 2 - 1].r = rr;
        q[i * 2].r = ll - 1;
        q[i * 2 - 1].id = q[i * 2].id = i;
        l[i] = ll - 1;
        A[i] = a;
        B[i] = b;
    }

    // cout << e[1].val;

    bit cnt;
    sort(q + 1, q + 2 * m + 1, cmpr);
    int shit = 1;
    for (int i = 1; i <= 2 * m; i++) if (q[i].r > 0) { shit = i; break; }
    CDQ(1, n, 1, 2 * m, cnt);

    for (int i = 1; i <= m; i++) cout << ans[i] << '\n';
    return 0;

}
2024/12/13 12:37
加载中...