洛谷P1972 [SDOI2009]HH的项链

 

题目背景

题目描述

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

输入输出格式

输入格式:

 

第一行:一个整数N,表示项链的长度。

第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。

第三行:一个整数M,表示HH 询问的个数。

接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

 

输出格式:

 

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

 

输入输出样例

输入样例#1:
6
1 2 3 4 3 5
3
1 2
3 5
2 6
输出样例#1:
2
2
4

说明

数据范围:

对于100%的数据,N <= 50000,M <= 200000。

 

 

区间无修改查询。

模板级别的莫队。

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 const int mxn=50010;
10 const int mxm=200010;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
15     return x*f;
16 }
17 struct query{
18     int l,r;
19     int m,id;
20 }c[mxm];
21 inline int cmp(query a,query b){
22     if(a.m!=b.m)return a.m<b.m;
23     return a.r<b.r;
24 }
25 int n,m;
26 int a[mxn];
27 int cnt[mxm*2],ans[mxn];
28 void work(){
29     register int l=1,r=0;
30     int tmp=0;
31     int i;
32     for(i=1;i<=m;++i){
33         while(r<c[i].r){
34             r++;
35             cnt[a[r]]++;
36             if(cnt[a[r]]==1) ++tmp;
37         }
38         while(l<c[i].l){
39             cnt[a[l]]--;
40             if(!cnt[a[l]]) --tmp;
41             l++;
42         }
43         while(r>c[i].r){
44             cnt[a[r]]--;
45             if(!cnt[a[r]]) --tmp;
46             r--;
47         }
48         while(l>c[i].l){
49             l--;
50             cnt[a[l]]++;
51             if(cnt[a[l]]==1) ++tmp;
52         }
53         ans[c[i].id]=tmp;
54     }
55     for(i=1;i<=m;i++)printf("%d\n",ans[i]);
56     return;
57 }
58 int main(){
59     n=read();
60     int i,j;
61     for(register int i=1;i<=n;++i){ a[i]=read(); }
62     m=read();
63     int block=sqrt(n);
64     for(register int i=1;i<=m;++i){
65         c[i].l=read();c[i].r=read();
66         c[i].id=i;
67         c[i].m=(c[i].l-1)/block+1;
68     }
69     sort(c+1,c+m+1,cmp);
70     work();
71     return 0;
72 }

 

posted @ 2016-10-20 18:00  SilverNebula  阅读(244)  评论(0编辑  收藏  举报
AmazingCounters.com