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

 

听说jump写了个树状数组,那么我就来个莫队祝祝兴吧

莫队水水的就水过去了0.0
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<cmath>
 8 #define yyj(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
 9 #define llg long long
10 #define maxn 1000010
11 struct node{
12     llg l,r,wz;
13 }c[maxn];
14 llg i,j,k[maxn],kl,x,n,m,a[maxn],l,r,ans[maxn],bj[maxn];
15 using namespace std;
16 bool cmp(const node & a,const node & b)
17 {
18     if (k[a.l]+1<k[b.l]+1) return true;
19     if (k[a.l]+1>k[b.l]+1) return false;
20     if (a.r<b.r) return true;else return false;                                          
21 }
22 int main()
23 {
24     yyj("a");
25     cin>>n;
26     kl=sqrt(n)+1;
27     while (i<=n)
28     {
29         j=kl; m++;
30         while (j--)
31         {
32             i++;
33             k[i]=m;
34         }
35     }
36     for (i=1;i<=n;i++) scanf("%lld",&a[i]);
37     cin>>m;
38     for (i=1;i<=m;i++) {scanf("%lld%lld",&c[i].l,&c[i].r); c[i].wz=i;}
39     sort(c+1,c+m+1,cmp);
40     l=c[1].l; r=c[1].r;
41     for (i=l;i<=r;i++)
42     {
43         if (!bj[a[i]])
44         {
45             ans[c[1].wz]++;
46         }
47         bj[a[i]]++;
48     }
49     for (i=2;i<=m;i++)
50     {
51         ans[c[i].wz]=ans[c[i-1].wz];
52         while (c[i].l>l)
53         {
54             bj[a[l]]--;
55             if (!bj[a[l]])
56             {
57                 ans[c[i].wz]--;
58             }
59             l++;
60         }
61         while (c[i].l<l)
62         {
63             l--;
64             bj[a[l]]++;
65             if (bj[a[l]]==1)
66             {
67                 ans[c[i].wz]++;
68             }
69         }
70         while (c[i].r<r)
71         {
72             bj[a[r]]--;
73             if (!bj[a[r]])
74             {
75                 ans[c[i].wz]--;
76             }
77             r--;
78         }
79         while (c[i].r>r)
80         {
81             r++;
82             bj[a[r]]+=1;
83             if (bj[a[r]]==1)
84             {
85                 ans[c[i].wz]+=1;
86             }
87         }
88     }
89     for (i=1;i<=m;i++) printf("%lld\n",ans[i]);
90     return 0;
91 }

想看树状数组解法的:http://www.cnblogs.com/ljh2000-jump/p/5607110.html

posted @ 2016-06-25 15:31  №〓→龙光←  阅读(138)  评论(0编辑  收藏  举报