牛客多校赛第一场 J Different Integers(莫队算法)

原题地址:https://www.nowcoder.com/acm/contest/139/J
题意:给出一个区间[i,j],询问[1,i]和[j,n]这两个区间有多少不同的数字。

思路:这题和之前写的莫队的入门题D-query特别的像,都是求区间上不同数字的个数。
但是之前的板子就是错的,这回换了一个板子。

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e5 + 5;
int cnt[maxn], a[maxn];
int n, m, block, ans, ansarr[maxn];
struct node {
    int l, r, id;
} e[maxn];
bool cmp(node a, node b) {
    if(a.l / block == b.l / block) return a.r < b.r;
    return a.l / block < b.l / block;
}

void add(int x) {
    ans += cnt[x] == 0 ? 1 : 0;
    cnt[x]++;
}
void del(int x) {
    cnt[x]--;
    ans -= cnt[x] == 0 ? 1 : 0;
}
int main() {
    while(~scanf("%d%d", &n, &m)) {
        memset(cnt, 0, sizeof(cnt));
        block = sqrt(n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        for(int i = 1; i <= m; i++) {
            scanf("%d%d", &e[i].l, &e[i].r);
            e[i].id = i;
        }
        sort(e + 1, e + 1 + m, cmp);
        ans = 0;
        int l = 0;
        int r = n + 1;
        for(int i = 1; i <= m; i++) {
            while(r > e[i].r) add(a[--r]);
            while(r < e[i].r) del(a[r++]);
            while(l < e[i].l) add(a[++l]);
            while(l > e[i].l) del(a[l--]);
            ansarr[e[i].id] = ans;
        }
        for(int i = 1; i <= m; i++) printf("%d\n", ansarr[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/81122190