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
1 2 3 4 3 5
3
1 2
3 5
2 6
Sample Output
2
2
4
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 }
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!