题目背景
无
题目描述
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 ",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 }