BZOJ 2743: [HEOI2012]采花

2743: [HEOI2012]采花

Time Limit: 15 Sec  Memory Limit: 128 MB
Submit: 2056  Solved: 1059
[Submit][Status][Discuss]

Description

萧芸斓是Z国的公主,平时的一大爱好是采花。
今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花。花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花。公主每次采花后会统计采到的花的颜色数,颜色数越多她会越高兴!同时,她有一癖好,她不允许最后自己采到的花中,某一颜色的花只有一朵。为此,公主每采一朵花,要么此前已采到此颜色的花,要么有相当正确的直觉告诉她,她必能再次采到此颜色的花。由于时间关系,公主只能走过花园连续的一段进行采花,便让女仆福涵洁安排行程。福涵洁综合各种因素拟定了m个行程,然后一一向你询问公主能采到多少朵花(她知道你是编程高手,定能快速给出答案!),最后会选择令公主最高兴的行程(为了拿到更多奖金!)。

Input

 

 第一行四个空格隔开的整数n、c以及m。接下来一行n个空格隔开的整数,每个数在[1, c]间,第i个数表示第i朵花的颜色。接下来m行每行两个空格隔开的整数l和r(l ≤ r),表示女仆安排的行程为公主经过第l到第r朵花进行采花。

Output

 
共m行,每行一个整数,第i个数表示公主在女仆的第i个行程中能采到的花的颜色数。

Sample Input

5 3 5
1 2 2 3 1
1 5
1 2
2 2
2 3
3 5

Sample Output

2
0 0 1 0
【样例说明】
询问[1, 5]:公主采颜色为1和2的花,由于颜色3的花只有一朵,公主不采;询问[1, 2]:颜色1和颜色2的花均只有一朵,公主不采;
询问[2, 2]:颜色2的花只有一朵,公主不采;
询问[2, 3]:由于颜色2的花有两朵,公主采颜色2的花;
询问[3, 5]:颜色1、2、3的花各一朵,公主不采。

HINT

 

【数据范围】

对于100%的数据,1 ≤ n ≤    10^6,c ≤ n,m ≤10^6。

 

Source

 
[Submit][Status][Discuss]

 

用莫队据说会TLE,有人实践了一下,@NEIGHTHORN

 那就只好离线+树状数组喽,预处理每种颜色的下一个出现位置,从左向右枚举左端点即可。

 

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

 

  1 #include <bits/stdc++.h>
  2 
  3 const int mxn = 1000005;
  4 
  5 int n, m, col[mxn];
  6 
  7 namespace BIT
  8 {
  9     int tree[mxn];
 10 
 11     void add(int p, int v)
 12     {
 13         for (; p <= n; p += p&-p)
 14             tree[p] += v;
 15     }
 16 
 17     int qry(int p)
 18     {
 19         int ret = 0;
 20 
 21         for (; p >= 1; p -= p&-p)
 22             ret += tree[p];
 23 
 24         return ret;
 25     }
 26 }
 27 
 28 namespace PRW
 29 {
 30     int nxt[mxn];
 31     int lst[mxn];
 32 
 33     void prework(void)
 34     {
 35         nxt[n + 1] = n + 1;
 36 
 37         for (int i = 1; i <= n + 1; ++i)
 38             lst[i] = n + 1;
 39 
 40         for (int i = n; i >= 1; --i)
 41         {
 42             nxt[i] = lst[col[i]];
 43             lst[col[i]] = i;
 44         }
 45 
 46         for (int i = 1; i <= n; ++i)
 47             BIT::add(nxt[lst[i]], 1);
 48     }
 49 }
 50 
 51 namespace QRY
 52 {
 53     struct query
 54     {
 55         int l, r, ans;
 56     }qry[mxn];
 57 
 58     int hd[mxn], to[mxn], nt[mxn], tot;
 59 
 60     void add(int u, int v)
 61     {
 62         nt[++tot] = hd[u], to[tot] = v, hd[u] = tot;
 63     }
 64 
 65     void read(int i)
 66     {
 67         scanf("%d%d", &qry[i].l, &qry[i].r);
 68 
 69         add(qry[i].l, i);
 70     }
 71 }
 72 
 73 signed main(void)
 74 {
 75     scanf("%d%*d%d", &n, &m);
 76 
 77     for (int i = 1; i <= n; ++i)
 78         scanf("%d", col + i);
 79 
 80     PRW::prework();
 81 
 82     for (int i = 1; i <= m; ++i)
 83         QRY::read(i);
 84 
 85     for (int i = 1; i <= n; ++i)
 86     {
 87         for (int j = QRY::hd[i]; j; j = QRY::nt[j])
 88         {
 89             int q = QRY::to[j];
 90 
 91             QRY::qry[q].ans = BIT::qry(QRY::qry[q].r);
 92         }
 93 
 94         BIT::add(PRW::nxt[i], -1);
 95         BIT::add(PRW::nxt[PRW::nxt[i]], 1);
 96     }
 97 
 98     for (int i = 1; i <= m; ++i)
 99         printf("%d\n", QRY::qry[i].ans);
100 }
View Code

 

@Author: YouSiki

posted @ 2016-12-20 17:31  YouSiki  阅读(138)  评论(0编辑  收藏  举报