BZOJ 1878: [SDOI2009]HH的项链

1878: [SDOI2009]HH的项链

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 3548  Solved: 1757
[Submit][Status][Discuss]

Description

HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。

Input

第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

Output

M行,每行一个整数,依次表示询问对应的答案。

Sample Input

6
1 2 3 4 3 5
3
1 2
3 5
2 6

Sample Output

2
2
4

HINT


对于20%的数据,N ≤ 100,M ≤ 1000;
对于40%的数据,N ≤ 3000,M ≤ 200000;
对于100%的数据,N ≤ 50000,M ≤ 200000。

Source

[Submit][Status][Discuss]

 

OTZ NEIGHTHORN

树状数组O(NlogN) 或 莫队算法O(N^1.5)

  1 #include <bits/stdc++.h>
  2 
  3 /* SCANNER */
  4 
  5 #define siz 1024
  6 
  7 inline int get_c(void)
  8 {
  9     static char buf[siz];
 10     static char *head = buf + siz;
 11     static char *tail = buf + siz;
 12     
 13     if (head == tail)
 14         fread(head = buf, 1, siz, stdin);
 15         
 16     return *head++;
 17 }
 18 
 19 inline int get_i(void)
 20 {
 21     register int ret = 0;
 22     register int neg = false;
 23     register int bit = get_c();
 24     
 25     for (; bit < 48; bit = get_c())
 26         if (bit == '-')neg ^= true;
 27         
 28     for (; bit > 47; bit = get_c())
 29         ret = ret * 10 + bit - 48;
 30         
 31     return neg ? -ret : ret;
 32 }
 33 
 34 #define N 50005
 35 #define M 200005
 36 #define V 1000005
 37 
 38 int n, m;
 39 int num[N];
 40 
 41 /* PREWORK */
 42 
 43 int nxt[N];
 44 int lst[V];
 45 int fst[V];
 46 
 47 /* QUERY */
 48 
 49 int lt[M];
 50 int rt[M];
 51 int ans[M];
 52 int ord[M];
 53 
 54 inline bool cmp(int a, int b)
 55 {
 56     return lt[a] < lt[b];
 57 }
 58 
 59 /* B I T */
 60 
 61 int tree[N];
 62 
 63 inline void add(int p, int k)
 64 {
 65     for (; p <= n; p += p&-p)
 66         tree[p] += k;
 67 }
 68 
 69 inline int ask(int p)
 70 {
 71     int ret = 0;
 72     for (; p >= 1; p -= p&-p)
 73         ret += tree[p];
 74     return ret;
 75 }
 76 
 77 /* MAIN */
 78 
 79 signed main(void)
 80 {
 81     n = get_i();
 82     
 83     for (int i = 1; i <= n; ++i)
 84         num[i] = get_i();
 85         
 86     for (int i = 0; i < V; ++i)
 87         lst[i] = n + 1;
 88         
 89     for (int i = n; i >= 1; --i)
 90         nxt[i] = lst[num[i]], lst[num[i]] = i;
 91         
 92     for (int i = 1; i <= n; ++i)
 93         if (!fst[num[i]])
 94         {
 95             add(i, 1);
 96             fst[num[i]] = 1;
 97         }
 98         
 99     m = get_i();
100     
101     for (int i = 1; i <= m; ++i)
102     {
103         ord[i] = i;
104         lt[i] = get_i();
105         rt[i] = get_i();
106     }
107     
108     std::sort(ord + 1, ord + 1 + m, cmp);
109     
110     int left = 1;
111     
112     for (int i = 1; i <= m; ++i)
113     {
114         while (left < lt[ord[i]])
115         {
116             add(left, -1);
117             add(nxt[left], 1);
118             ++left;
119         }
120         
121         ans[ord[i]] = ask(rt[ord[i]]);
122     }
123     
124     for (int i = 1; i <= m; ++i)
125         printf("%d\n", ans[i]);
126 }

 

@Author: YouSiki

posted @ 2016-12-20 16:29  YouSiki  阅读(171)  评论(0编辑  收藏  举报