首页 > 代码库 > SPOJ D-query(莫队算法模板)

SPOJ D-query(莫队算法模板)

题目链接:http://www.spoj.com/problems/DQUERY/

题目大意:给定一个数组,每次询问一个区间内的不同元素的个数

解题思路:直接套莫队的裸体

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const int N=3e5+5;//区间范围 
 7 const int MAX=1e6+5;//最大数字 
 8 int unit,cnt[MAX],arr[N],res[N],ans=0;
 9 
10 struct node{
11     int l,r,id;
12 }q[N];
13 
14 bool cmp(node a,node b){
15     return a.l/unit!=b.l/unit?a.l/unit<b.l/unit:a.r<b.r;
16 }
17 
18 void add(int pos){
19     cnt[arr[pos]]++;
20     if(cnt[arr[pos]]==1){
21         ans++;
22     }
23 }
24 
25 void remove(int pos){
26     cnt[arr[pos]]--;
27     if(cnt[arr[pos]]==0){
28         ans--;
29     }
30 }
31 
32 int main(){
33     int n;
34     scanf("%d",&n);
35     unit=sqrt(n);
36     for(int i=1;i<=n;i++){
37         scanf("%d",&arr[i]);
38     }    
39     int m;
40     scanf("%d",&m);
41     for(int i=1;i<=m;i++){
42         scanf("%d%d",&q[i].l,&q[i].r);
43         q[i].id=i;
44     }
45     
46     sort(q+1,q+m+1,cmp);
47     
48     int L=q[1].l,R=L-1;
49     for(int i=1;i<=m;i++){
50         while(L>q[i].l)
51             add(--L);
52         while(L<q[i].l)
53             remove(L++);
54         while(R>q[i].r)
55             remove(R--);
56         while(R<q[i].r)
57             add(++R);
58         res[q[i].id]=ans;
59     }
60     for(int i=1;i<=m;i++){
61         printf("%d\n",res[i]);
62     }
63 }

 

SPOJ D-query(莫队算法模板)