平方分割(莫队算法)

莫队算法通常用来解决一类多次区间询问问题,使用该算法有两个要求:

处理流程大致如下:

例题:给定正整数数组a[n]和q组问询(l,r),对于每次问询,输出区间(l,r)包含多少个不同的数。

以下代码评测会超时,加入快速输入可以通过。

#include <bits/stdc++.h>
using namespace std;
int n, a[30005], m, cnt[1000005], bs, L, R, ans[200005], cur;
struct st {
    int l, r, x;
    bool operator<(const st &u) const {
        if (l/bs == u.l/bs) return r < u.r;
        return l < u.l;
    }
}q[200005];
void add(int x) {
    if (++cnt[x] == 1) cur++;
}
void del(int x) {
    if (--cnt[x] == 0) cur--;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", a+i);
    scanf("%d", &m);
    bs = sqrt(m);
    for (int i = 1; i <= m; i++) {
        scanf("%d%d", &q[i].l, &q[i].r);
        q[i].x = i;
    }
    sort(q+1, q+1+m);
    for (int i = 1; i <= m; i++) {
        while (L < q[i].l) del(a[L++]);
        while (L > q[i].l) add(a[--L]);
        while (R < q[i].r) add(a[++R]);
        while (R > q[i].r) del(a[R--]);
        ans[q[i].x] = cur;
    }
    for (int i = 1; i <= m; i++)
        printf("%d\n", ans[i]);
    return 0;
} 
Table of Contents