P3901 数列找不同

题意:每次询问一个区间里的数是否各不相同

显然,当一个区间里的数各不相同时,它们的种数就是区间的长度

莫队可以快速地求出区间的颜色种数,因此强制离线计算即可

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, q, a[N], block, ans = 0, cnt[N], Ans[N];

struct Question {
    int l, r, idx;
}Q[N];

struct Temp {
    int l, r; 
}u[N];

void add(int x) {
    if(!cnt[a[x]]) ans++;
    cnt[a[x]]++;
}

void del(int x) {
    cnt[a[x]]--;
    if(!cnt[a[x]]) ans--;
}


template <typename T>
inline void read(T &t) {
    t = 0; T m = 1; char ch = getchar();
    while(ch < '0' || ch > '9') { if(ch == '-') m = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') { t = (t << 3) + (t << 1) + (ch & 15); ch = getchar(); }
    t *= m;
}

bool cmp(const Question &a, const Question &b) {
    return a.r / block == b.r / block ? a.l < b.l : a.r < b.r;
}

int main() {
    read(n), read(q);
    block = n / sqrt(q * 2 / 3);
    for(int i = 1; i <= n; i++) {
        read(a[i]);
    }
    for(int i = 1; i <= q; i++) {
        read(Q[i].l), read(Q[i].r); Q[i].idx = i;
        u[i].l = Q[i].l, u[i].r = Q[i].r;
    }
    sort(Q + 1, Q + q + 1, cmp);
    int l = 0, r = 0;
    for(int i = 1; i <= q; i++) {
        int L = Q[i].l, R = Q[i].r;
        while(l < L) del(l++);
        while(l > L) add(--l);
        while(r < R) add(++r);
        while(r > R) del(r--);
        Ans[Q[i].idx] = ans;
    }
    for(int i = 1; i <= q; i++) {
        if(Ans[i] == u[i].r - u[i].l + 1) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
posted @ 2019-01-08 14:18  Chloristendika  阅读(130)  评论(0编辑  收藏  举报