SPOJ3267--D-query (树状数组离线操作)

题意查询区间 [l,r]内有多少个不同的数字

先把所有询问按 右端点进行排序,然后离线操作。如果该位置的数字 已经出现过那么把前一个位置-1,当前位置+1。扫一遍输出。

 1 #include <cstdio>

 2 #include <string>

 3 #include <vector>

 4 #include <cstdlib>

 5 #include <cstring>

 6 #include <algorithm>

 7 using namespace std;

 8 

 9 const int maxq = 2e5+10;

10 const int maxn = 3e4+10;

11 int last[1000050];

12 int n,m,c[maxn],ans[200005];

13 struct Node

14 {

15     int l,r,ans,idx;

16     bool operator < (const Node &rhs)const

17     {

18         return r < rhs.r || (r == rhs.r && l < rhs.l);

19     }

20 }Q[maxq];

21 int lowbit(int x)

22 {

23     return x & -x;

24 }

25 void add(int x,int d)

26 {

27     while (x <= maxn)

28     {

29         c[x] += d;

30         x += lowbit(x);

31     }

32 }

33 int sum(int x)

34 {

35     int ans = 0;

36     while (x)

37     {

38         ans += c[x];

39         x -= lowbit(x);

40     }

41     return ans;

42 }

43 int a[maxq];

44 int main(void)

45 {

46     #ifndef ONLINE_JUDGE

47         freopen("in.txt","r",stdin);

48     #endif

49     while (~scanf ("%d",&n))

50     {

51         memset(c,0,sizeof(c));

52         memset(last,-1,sizeof(last));

53         for (int i = 2; i <= n+1; i++)

54             scanf ("%d",a+i);

55         scanf ("%d",&m);

56         for (int i = 0; i < m; i++)

57         {

58             Q[i].idx = i;

59             scanf ("%d%d",&Q[i].l,&Q[i].r);

60             Q[i].l++,Q[i].r++;

61         }

62         sort(Q,Q+m);

63         int pre = 2;

64         for (int i = 0; i < m; i++)

65         {

66             for(int j =  pre; j <= Q[i].r; j++)

67             {

68                 if (~last[a[j]])

69                 {

70                     add(last[a[j]],-1);

71                     add(j,1);

72                 }

73                 else

74                 {

75                     add(j,1);

76                 }

77                 last[a[j]] = j;

78             }

79             ans[Q[i].idx] = sum(Q[i].r) - sum(Q[i].l - 1);

80             pre = Q[i].r+1;

81         }

82         for (int i = 0; i < m; i++)

83             printf("%d\n",ans[i]);

84     }

85     return 0;

86 }

 

此题主席树也可以做。

 

你可能感兴趣的:(query)