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
1 2 3 4 3 5
3
1 2
3 5
2 6
Sample Output
2
2
4
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\n", ans[i]); 56 57 return 0; 58 }