题目链接:http://www.spoj.com/problems/DQUERY/
题目:
Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.
Input
- Line 1: n (1 ≤ n ≤ 30000).
- Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
- Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
- In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).
Output
- For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.
Example
Input 5 1 1 2 1 3 3 1 5 2 4 3 5 Output 3 2 3
题意:给定一个序列,询问m次,每次求出区间 [ L,R ] 不同数字出现的次数。
题解:莫队模板题
1 #include <cmath> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 6 const int N=1e6+10; 7 struct node{ 8 int l,r,id; 9 }Q[N]; 10 11 int a[N],ans[N],cnt[N],BLOCK; 12 bool cmp(node x,node y){ 13 if(x.l/BLOCK==y.l/BLOCK) return x.r<y.r; 14 return x.l/BLOCK<y.l/BLOCK; 15 } 16 17 int n,m,Ans=0; 18 19 void add(int x){ 20 cnt[a[x]]++; 21 if(cnt[a[x]]==1) Ans++; 22 } 23 24 void del(int x){ 25 cnt[a[x]]--; 26 if(cnt[a[x]]==0) Ans--; 27 } 28 29 int main(){ 30 scanf("%d",&n); 31 BLOCK=sqrt(n); 32 for(int i=1;i<=n;i++){ 33 scanf("%d",&a[i]); 34 } 35 scanf("%d",&m); 36 for(int i=1;i<=m;i++){ 37 scanf("%d%d",&Q[i].l,&Q[i].r); 38 Q[i].id=i; 39 } 40 sort(Q+1,Q+1+m,cmp); 41 int L=1,R=0; 42 for(int i=1;i<=m;i++){ 43 while(L<Q[i].l){ 44 del(L); 45 L++; 46 } 47 while(L>Q[i].l){ 48 L--; 49 add(L); 50 } 51 while(R<Q[i].r){ 52 R++; 53 add(R); 54 } 55 while(R>Q[i].r){ 56 del(R); 57 R--; 58 } 59 ans[Q[i].id]=Ans; 60 } 61 for(int i=1;i<=m;i++) 62 printf("%d\n",ans[i]); 63 return 0; 64 }