SPOJ 3267 求区间不同数的个数

题意:给定一个数列,每次查询一个区间不同数的个数。

做法:离线+BIT维护。将查询按右端点排序。从左到右扫,如果该数之前出现过,则将之前出现过的位置相应删除;当前位置则添加1。这样做就保证每次扫描到的某一位置,以该位置为右端点的区间都相应地确定了。

 1 /*
 2  *Author:       Zhaofa Fang
 3  *Created time: 2013-08-25-22.29 星期日
 4  */
 5 #include <cstdio>
 6 #include <cstdlib>
 7 #include <sstream>
 8 #include <iostream>
 9 #include <cmath>
10 #include <cstring>
11 #include <algorithm>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 #include <queue>
16 #include <map>
17 #include <set>
18 using namespace std;
19 
20 typedef long long ll;
21 typedef pair<int,int> PII;
22 #define DEBUG(x) cout<< #x << ':' << x << endl
23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
25 #define REP(i,n) for(int i=0;i<(n);i++)
26 #define REPD(i,n) for(int i=(n-1);i>=0;i--)
27 #define PII pair<int,int>
28 #define PB push_back
29 #define ft first
30 #define sd second
31 #define lowbit(x) (x&(-x))
32 #define INF (1<<30)
33 #define eps (1e-8)
34 
35 const int maxq = 200011;
36 const int maxn = 30011;
37 int a[maxn],C[maxn],last[1000011];
38 int ans[maxq];
39 void init(){
40     memset(C,0,sizeof(C));
41     memset(last,-1,sizeof(last));
42 }
43 struct Query{
44     int l,r;
45     int idx;
46     bool operator < (const Query & rhs)const{
47         return r < rhs.r;
48     }
49 }Q[maxq];
50 
51 void add(int x,int val){
52     while(x<maxn){
53         C[x] += val;
54         x += lowbit(x);
55     }
56 }
57 int sum(int x){
58     int res = 0;
59     while(x > 0){
60         res += C[x];
61         x -= lowbit(x);
62     }
63     return res;
64 }
65 int main(){
66     //freopen("in","r",stdin);
67     //freopen("out","w",stdout);
68     int n;
69     while(~scanf("%d",&n)){
70         init();
71         FOR(i,1,n)scanf("%d",&a[i]);
72         int q;
73         scanf("%d",&q);
74         REP(i,q){
75             scanf("%d%d",&Q[i].l,&Q[i].r);
76             Q[i].idx = i;
77         }
78         sort(Q,Q+q);
79         int pre = 1;
80         REP(i,q){
81             FOR(j,pre,Q[i].r){
82                 if(last[a[j]]==-1){
83                     add(j,1);
84                 }else {
85                     add(last[a[j]],-1);
86                     add(j,1);
87                 }
88                 last[a[j]] = j;
89             }
90             ans[Q[i].idx] = sum(Q[i].r)-sum(Q[i].l-1);
91             pre = Q[i].r+1;
92         }
93         REP(i,q)printf("%d\n",ans[i]);
94     }
95     return 0;
96 }
View Code

 

posted @ 2013-08-26 00:13  發_  阅读(555)  评论(0编辑  收藏  举报