zoukankan      html  css  js  c++  java
  • BZOJ2120 数颜色Count

    Description

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

    Input

    第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

    Output

    对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

    Sample Input

    6 5

    1 2 3 4 5 5

    Q 1 4

    Q 2 6

    R 1 2

    Q 1 4

    Q 2 6

    Sample Output

    4

    4

    3

    4

    HINT

    对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。


    DreifO_o很不爽因为......她只不过写了写弹飞绵羊的代码啊(题解不还是我写的)...;

    总之今天需要第二篇题解来缓和一下气氛;

    和她一样吧...也是一道分块可做题.


    这道题的分块更优美,优雅的暴力hhh;

    对于序列中的每一个数:维护之前与它颜色相同的最近的一个块的位置,放在pre数组中;

    然后!现在对于每一次询问,实际上是求出该区间中所有pre值小于l的值的数量,暴力扫一遍明显太慢而且与分块无关了,

    所以我们可以对整块二分,残块暴力!

    详见代码:

     1 //2120 数颜色 Count__From BZOJ
     2 //Bucket Method & Binary Search
     3 #include<iostream>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 
     9 inline void Read(int&);
    10 const int maxn = 10000 + 5;
    11 int n, m, q, num;
    12 int arr[maxn], pre[maxn];
    13 int blo[maxn], temp[maxn]/*用来二分的数组*/;
    14 int last[1000000 + 5];
    15 void Update(int);
    16 int Binary(int, int);
    17 
    18 int main()
    19 {
    20     Read(n), Read(q);
    21     m = sqrt(n), num = (n - 1) / m + 1;
    22     for (int i = 1; i <= n; i++) {
    23         blo[i] = (i - 1) / m + 1;
    24         Read(arr[i]);
    25         pre[i] = last[arr[i]];//维护pre
    26         last[arr[i]] = i;
    27     }
    28     for (int i = 1; i <= num; i++) Update(i);//处理一下temp;
    29     char ord;
    30     int l, r;
    31     while (q--) {
    32         scanf("%s", &ord);
    33         Read(l), Read(r);
    34         if (ord == 'Q') {
    35             int ans = 0, end = min(r, blo[l] * m);
    36             for (int i = l; i <= end; i++)
    37                 if (pre[i] < l) ans++;
    38             end = (blo[r] - 1)*m + 1;
    39             if (blo[l] != blo[r])
    40                 for (int i = r; i >= end; i--)
    41                     if (pre[i] < l) ans++;
    42             end = blo[r] - 1;
    43             for (int i = blo[l] + 1; i <= end; i++)
    44                 ans += Binary(i, l);//二分查找
    45             printf("%d
    ", ans);
    46         }
    47         else {//暴力的修改
    48             for (int i = 1; i <= n; i++) last[arr[i]] = 0;
    49             arr[l] = r;
    50             for (int i = 1; i <= n; i++) {
    51                 int tmp = pre[i];
    52                 pre[i] = last[arr[i]];
    53                 if (tmp != pre[i]) Update(blo[i]);
    54                 last[arr[i]] = i;
    55             }
    56         }
    57     }
    58     return 0;
    59 }
    60 
    61 int Binary(int k, int ans)
    62 {
    63     int l = (k - 1)*m + 1, r = k*m;
    64     while (l <= r) {
    65         int mid = l + r >> 1;
    66         if (temp[mid] < ans) l = mid + 1;
    67         else r = mid - 1;
    68     }
    69     return l - (k - 1)*m - 1;
    70 }
    71 
    72 void Update(int k)
    73 {
    74     int l = (k - 1)*m + 1, r = min(k*m, n);
    75     for (int i = l; i <= r; i++)
    76         temp[i] = pre[i];
    77     sort(temp + l, temp + r + 1);//二分要求数组有序
    78 }
    79 
    80 inline void Read(int &x)
    81 {
    82     x = 0;
    83     bool f = 0;
    84     char c = getchar();
    85     while (c < '0' || c > '9') {
    86         f = (c == '-');
    87         c = getchar();
    88     }
    89     while (c >= '0'&&c <= '9') {
    90         x = x * 10 + c - '0';
    91         c = getchar();
    92     }
    93     if (f) x = -x;
    94 }
  • 相关阅读:
    artDialog基本使用
    SQL数据类型(SQL Server六个类型使用)
    常用SQL语句大全(SQL Server)
    从PRISM开始学WPF(八)导航Navigation-更新至Prism7.1
    从PRISM开始学WPF(番外)共享上下文 RegionContext-更新至Prism7.1
    从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1
    从PRISM开始学WPF(六)MVVM(二)Command-更新至Prism7.1
    从PRISM开始学WPF(四)Prism-Module-更新至Prism7.1
    从PRISM开始学WPF(二)认识Prism-更新至Prism7.1
    从PRISM开始学WPF(一)认识WPF-更新至Prism7.1
  • 原文地址:https://www.cnblogs.com/DreifxP/p/7719042.html
Copyright © 2011-2022 走看看