BZOJ1878 [SDOI2009]HH的项链

 

Description

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

Input

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

Output

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

Sample Input

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

Sample Output

2
2
4

HINT


对于20%的数据,N ≤ 100,M ≤ 1000;
对于40%的数据,N ≤ 3000,M ≤ 200000;
对于100%的数据,N ≤ 50000,M ≤ 200000。

Source

 
正解:树状数组
解题报告:
  以前有一次考试的时候写过这道题,当时就A掉了,就当重写一次了。。。
  这道题显然还有莫队、kd-tree可做,有时间再打吧。
 
 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 #ifdef WIN32   
14 #define OT "%I64d"
15 #else
16 #define OT "%lld"
17 #endif
18 using namespace std;
19 typedef long long LL;
20 const int MAXN = 50011;
21 const int MAXS = 1000011;
22 const int MAXM = 200011;
23 int num[MAXN],pre[MAXS],shu[MAXS];
24 int n,m,ans;
25 
26 struct wen{
27     int l,r,ans,jilu;
28 }q[MAXM];
29 
30 inline int getint()
31 {
32        int w=0,q=0;
33        char c=getchar();
34        while((c<'0' || c>'9') && c!='-') c=getchar();
35        if (c=='-')  q=1, c=getchar();
36        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
37        return q ? -w : w;
38 }
39 
40 inline bool cmp(wen q,wen qq){ return q.r<qq.r;}
41 
42 inline bool comp(wen q,wen qq){ return q.jilu<qq.jilu; }
43 
44 inline void add(int x,int val){
45     while(x<=n){
46     shu[x]+=val;
47     x+=x&(-x);
48     }
49 }
50 
51 inline int query(int x){
52     int total=0;
53     while(x>0) {
54     total+=shu[x];
55     x-=x&(-x);
56     }
57     return total;
58 }
59 
60 inline void solve(){
61     n=getint(); for(int i=1;i<=n;i++) num[i]=getint();
62     m=getint(); for(int i=1;i<=m;i++) q[i].l=getint(),q[i].r=getint(),q[i].jilu=i;
63     sort(q+1,q+m+1,cmp);
64     int now=1;
65     for(int i=1;i<=n;i++) {
66     if(pre[num[i]]) add(pre[num[i]],-1);
67     add(i,1);
68     pre[num[i]]=i;
69     if(q[now].r==i) {
70         ans=query(i);
71     }
72     while(q[now].r==i) { q[now].ans=ans-query(q[now].l-1); now++; }
73     }
74     sort(q+1,q+m+1,comp);
75     for(int i=1;i<=m;i++)  printf("%d\n",q[i].ans);
76 }
77 
78 int main()
79 {
80   solve();
81   return 0;
82 }

 

posted @ 2016-06-22 14:55  ljh_2000  阅读(352)  评论(0编辑  收藏  举报