BZOJ1878: [SDOI2009]HH的项链

Description

HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一
段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一
个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只
好求助睿智的你,来解决这个问题。

Input

第一行:一个整数N,表示项链的长度。 
第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 
第三行:一个整数M,表示HH询问的个数。 
接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
N ≤ 50000,M ≤ 200000。

Output

M行,每行一个整数,依次表示询问对应的答案。

Sample Input

6
1 2 3 4 3 5
3
1 2
3 5
2 6

Sample Output

2
2
4
 
树状数组的奇淫技巧....看网上题解才会的.......
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 1000001;
 7 
 8 struct node{
 9     int l, r, id;
10 }a[N];
11 int pre[N], col[N], c[N], ans[N], last[N];
12 int n, m;
13 
14 int lowbit(int x){
15     return x & (-x);
16 }
17 void updata(int x, int p){
18     for(int i=x; i<=n; i+=lowbit(i)) c[i] += p;
19 }
20 int getsum(int x){
21     int res = 0;
22     for(int i=x; i; i-=lowbit(i)) res += c[i];
23     return res;
24 }
25 
26 int cmp(node a, node b){
27     return a.r < b.r;
28 }
29 
30 int main(){
31     scanf("%d", &n);
32     for(int i=1;i<=n;i++){
33         scanf("%d", &col[i]);
34         pre[i] = last[col[i]];
35         last[col[i]] = i;
36     }
37     scanf("%d", &m);
38     for(int i=1;i<=m;i++){
39         scanf("%d%d", &a[i].l, &a[i].r);
40         a[i].id = i;
41     }
42     sort(a+1, a+1+m, cmp);
43     int now = 0;
44     for(int i=1;i<=m;i++){
45         while(now < a[i].r){
46             now++;
47             updata(pre[now]+1, 1);
48             if(now != n){
49                 updata(now+1, -1);
50             }    
51         }
52         ans[a[i].id] = getsum(a[i].l);
53     }
54     for(int i=1;i<=m;i++)
55         printf("%d
", ans[i]);
56 
57     return 0;
58 }
原文地址:https://www.cnblogs.com/sineagle/p/8454405.html