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

 

你可能感兴趣的:(poj)