^m
路漫漫

题意:n个数 a1...an,q组询问,每组询问给定 l,r,输出 [ l, r ] 有多少不同的数 ( n ≤30000, q ≤200000, ai ≤ 106 )

离线 + 树状数组维护

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4 
 5 const int MAXN = 2333666;
 6 int n, a[MAXN], start[MAXN], nex[MAXN], q, t[MAXN], an[MAXN], k[MAXN];
 7 pair<int, int> Q[MAXN];
 8 
 9 template <typename tn> void read (tn & a) {
10     tn x = 0, f = 1;
11     char c = getchar();
12     while (c < '0' || c > '9'){ if (c == '-') f = -1; c = getchar(); }
13     while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar(); }
14     a = f == 1 ? x : -x;
15 }
16 
17 void add (int k, int d) {
18     while (k <= n) {
19         t[k] += d;
20         k += k & -k;
21     }
22 }
23 
24 int sum (int k) {
25     int s = 0;
26     while (k > 0) {
27         s += t[k];
28         k -= k & -k;
29     }
30     return s;
31 }
32 
33 bool cmp (const int &i, const int & j) {
34     return Q[i] < Q[j];
35 }
36 
37 int main() {
38     read(n);
39     for (int i = 1; i <= n; ++i) {
40         read(a[i]);
41     }
42     for (int i = n; i >= 1; --i) {
43         if (start[a[i]] != 0) add(start[a[i]], -1);
44         add(i, 1);
45         nex[i] = start[a[i]];
46         start[a[i]] = i;
47     }
48     read(q);
49     for (int i = 1; i <= q; ++i) {
50         read(Q[i].first);
51         read(Q[i].second);
52     }
53     for (int i = 1; i <= q; ++i) k[i] = i;
54     sort(k + 1, k + 1 + q, cmp);
55     int lx = 1;
56     for (int i = 1; i <= q; ++i) {
57         while (Q[k[i]].first > lx) {
58             if (sum(lx) - sum(lx - 1) > 0) {
59                 if (nex[lx] != 0) add(nex[lx], 1);
60                 add(lx, -1);
61             }
62             ++lx;
63         }
64         an[k[i]] = sum(Q[k[i]].second) - sum(Q[k[i]].first - 1);
65     }
66     for (int i = 1; i <= q; ++i) printf("%d ", an[i]); printf("\n");
67     return 0;
68 } 
View Code

 

posted on 2018-03-20 18:19  ^m  阅读(122)  评论(0编辑  收藏  举报