莫队算法

莫队算法

莫队算法文档

DQUERY

Given a sequence of n numbers a1, a2, …, an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, …, aj.

解法

离线修改查询次序,莫队。 之前写的挫,看到这个写的比较好。

代码

#include
#include

using namespace std;

const int SIZE = 300005;
const int CSIZE = 1000005;
const int BLOCK = 555;

int cnt[CSIZE], a[SIZE], res[SIZE], ans;

struct node {
    int L, R, i;
} q[SIZE];

bool cmp(const node &x, const node &y) {
    if(x.L/BLOCK != y.L/BLOCK) return x.L/BLOCK < y.L/BLOCK;
    return x.R < y.R;
}

void add(int pos) {
    cnt[a[pos]]++;
    if(cnt[a[pos]] == 1) ans++;
}

void remove(int pos) {
    cnt[a[pos]]--;
    if(!cnt[a[pos]]) ans--;
}

int main() {
    int N;
    scanf("%d",&N);
    for(int i = 1; i <= N; i++) scanf("%d",&a[i]);
    int Q;
    scanf("%d",&Q);
    for(int i = 1; i <= Q; i++) {
        scanf("%d%d",&q[i].L, &q[i].R);
        q[i].i = i;
    }
    sort(q + 1, q + 1 + Q, cmp);
    int l = 1, r = 1;
    for(int i = 1; i <= Q; i++) {
        int L = q[i].L, R = q[i].R;
        while(l < L) remove(l++);
        while(l > L) add((l--) - 1);
        while(r <= R) add(r++);
        while(r > R+1) remove((r--) - 1);
        res[q[i].i] = ans;
    }
    for(int i = 1; i <= Q; i++) printf("%d\n",res[i]);

}

你可能感兴趣的:(算法,Mo,莫队,Mo-s)