2018 Nowcoder 멀티 - 대학 교육 경연 대회 1

연습 링크

J. 다른 정수

질문의 의미
부여는 \ (n \) 수는 때마다 물어 \ ((L_i는 r_i) \) , 대표 \ (A_1, \ cdots, A_I , a_j, \ cdots, a_n \) 에서 어떻게 다양한 수.

아이디어 :
첫째, 각각 계산 오프라인 \ (A_1, \ cdots A_I \ ) 와 \ (a_j, \ cdots, a_n \) 얼마나 많은이 다른 번호.
얼마나 많은 양 수가 고려 \ ([1, 난] \ ) 또한 (\ [N, J를] \ ) , 후 오프라인으로 수행.
처음으로 수를 고려하는 시간, 모든 문의 섹션의 위치는이 숫자는 첫째로 나타나고 기여를 뺀.

코드 :

#include <bits/stdc++.h>
using namespace std;

#define N 100010
int n, q, a[N], b[N], c[N], nx[N], ans[N];
struct node {
    int l, r, id;
    node() {}
    void scan(int id) {
        this->id = id;
        scanf("%d%d", &l, &r);
        if (l >= r) {
            l = 1;
            r = 2;  
        }
    }
}qrr[N];

struct BIT {
    int a[N];
    void init() {
        memset(a, 0, sizeof a);
    }
    void update(int x, int v) {
        for (; x > 0; x -= x & -x) {
            a[x] += v;
        }
    }
    int query(int x) {
        int res = 0;
        for (; x < N; x += x & -x) {
            res += a[x];
        }
        return res;
    }
    int query(int l, int r) {
        return query(l) - query(r + 1);
    }
}bit; 

int main() {
    while (scanf("%d%d", &n, &q) != EOF) {
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
        }
        for (int i = 1; i <= q; ++i) {
            qrr[i].scan(i);
        }
        if (n == 1) {
            for (int i = 1; i <= q; ++i) {
                printf("1\n");
            }
            continue;
        }
        sort(qrr + 1, qrr + 1 + q, [&](node x, node y) {
            return x.l < y.l;       
        });
        memset(b, 0, sizeof b);
        for (int i = 1, j = 1, k = 0; i <= q; ++i) {
            while (j <= n && j <= qrr[i].l) {
                if (b[a[j]] == 0) {
                    b[a[j]] = 1;
                    ++k;
                }
                ++j;
            }
            ans[qrr[i].id] = k;
        }
        sort(qrr + 1, qrr + 1 + q, [&](node x, node y){  
            return x.r > y.r;       
        });
        memset(b, 0, sizeof b);
        for (int i = 1, j = n, k = 0; i <= q; ++i) {
            while (j >= 1 && j >= qrr[i].r) {
                if (b[a[j]] == 0) {
                    b[a[j]] = 1;
                    ++k;
                }
                --j;
            }
            ans[qrr[i].id] += k;
        }
        memset(b, 0, sizeof b); 
        for (int i = 1; i <= n; ++i) {
            nx[i] = n + 1;
        }
        for (int i = n; i >= 1; --i) { 
            c[i] = nx[a[i]]; 
            if (nx[a[i]] == n + 1) {
                nx[a[i]] = i;    
            }
        }
        bit.init();
        sort(qrr + 1, qrr + 1 + q, [&](node x, node y){
            return x.l < y.l;       
        });
        for (int i = 1, j = 1; i <= q; ++i) {
            while (j <= n && j <= qrr[i].l) {
                if (b[a[j]] == 0) {
                    bit.update(c[j], -1);
                    b[a[j]] = 1;    
                }
                ++j; 
            }
            ans[qrr[i].id] += bit.query(qrr[i].r, n); 
        }
        for (int i = 1; i <= q; ++i) {
            printf("%d\n", ans[i]);
        }
    }
    return 0;
}

추천

출처www.cnblogs.com/Dup4/p/11108577.html