1. 程式人生 > 其它 >SP3267 DQUERY - D-query題解 莫隊演算法入門

SP3267 DQUERY - D-query題解 莫隊演算法入門

題目連結:https://www.luogu.com.cn/problem/SP3267

參考連結:https://www.cnblogs.com/cjjsb/p/9539388.html

題目大意:

區間詢問共有多少不同數值。

示例程式:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e4 + 5, maxm = 1e6 + 5, maxq = 2e5 + 5;
struct Query {
    int l, r, res, id;
} q[maxq];
int n, m, block, a[maxn], bl[maxn], cnt[maxm], ans;

bool cmp1(Query a, Query b) {
    return bl[a.l] < bl[b.l] || bl[a.l] == bl[b.l] && (bl[a.l]&1 ? a.r<b.r : a.r > b.r);
}

bool cmp2(Query a, Query b) {
    return a.id < b.id;
}

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

void del(int v) {
    if (--cnt[v] == 0) ans--;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n;
    block = sqrt(n);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        bl[i] = (i - 1) / block + 1;
    }
    cin >> m;
    for (int i = 0; i < m; i++) {
        q[i].id = i;
        cin >> q[i].l >> q[i].r;
    }
    sort(q, q+m, cmp1);
    int l = q[0].l, r = q[0].l-1;
    for (int i = 0; i < m; i++) {
        while (r != q[i].r) {
            (r < q[i].r) ? add(a[++r]) : del(a[r--]);
        }
        while (l != q[i].l) {
            (l < q[i].l) ? del(a[l++]) : add(a[--l]);
        }
        q[i].res = ans;
    }
    sort(q, q+m, cmp2);
    for (int i = 0; i < m; i++)
        cout << q[i].res << endl;
    return 0;
}