zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", QRY::qry[i].ans);
    100 }
    View Code

    @Author: YouSiki

  • 相关阅读:
    重建Exchange邮件系统的系统邮箱
    枚举算法001
    关于网站备案的44个问题
    wireshack使用
    格言
    程序员遇到BUG的解释
    只要有信心任何事情都可以做成,今天表现不错哦,加油!
    踏实,自信
    学会经营自己的关系
    戒酒
  • 原文地址:https://www.cnblogs.com/yousiki/p/6203482.html
Copyright © 2011-2022 走看看