SP3267 DQUERY - D-query(莫队模板)

题意: 给出一个长度为n 的数列, a 1 , a 2 , . . . , a n a_{1},a_{2},...,a_{n} a1,a2,...,an ​ ,有q 个询问,每个询问给出数对 ( i , j ) (i,j) (i,j),需要你给出 a i , a i + 1 , . . . , a j a_{i} ,a_{i+1},...,a_{j} aiai+1...aj这一段中有多少不同的数字
思路 莫队

#include
#pragma GCC optimize(2)
#define ll long long
using namespace std;
const int N = 3e4 + 10;
int n, m, a[N], cnt[N * 40], bel[N * 40], now, ans[N * 7];
struct node {
    int l, r, id;
    bool operator < (const node &b)const {
        return (bel[l] ^ bel[b.l]) ? bel[l] < bel[b.l] : ((bel[l] & 1) ? r < b.r : r > b.r);
    }
} no[N * 7];
void add(int pos) {
    if(!cnt[a[pos]])
        ++now;
    ++cnt[a[pos]];
}
void del(int pos) {
    --cnt[a[pos]];
    if(!cnt[a[pos]])
        --now;
}
int main() {
    scanf("%d", &n);
    int sz = sqrt(n);
    int kuai = ceil((double)n / sz);
    for(int i = 1; i <= kuai; i++)
        for(int j = (i - 1) * sz + 1; j <= i * sz; j++)
            bel[j] = i;
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    scanf("%d", &m);
    for(int i = 1; i <= m; i++)
        scanf("%d%d", &no[i].l, &no[i].r), no[i].id = i;
    sort(no + 1, no + m + 1);
    int l = 1, r = 0;
    for(int i = 1; i <= m; i++) {
        int ql = no[i].l, qr = no[i].r;
        while(l < ql)
            del(l++);
        while(l > ql)
            add(--l);
        while(r < qr)
            add(++r);
        while(r > qr)
            del(r--);
        ans[no[i].id] = now;
    }
    for(int i = 1; i <= m; i++)
        printf("%d\n", ans[i]);
    return 0;
}

你可能感兴趣的:(莫队)