zoukankan      html  css  js  c++  java
  • BZOJ-2120-数颜色(暴力/分块)

    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。


    2016.3.2新加数据两组by Nano_Ape

    Source

    题解

    这道题暴力也可以水过(但是不知道为什么离散化后效率会快很多0.0)

     1 #include<bits/stdc++.h>
     2 #define N 10005
     3 #define M 1000005
     4 using namespace std;
     5 int n,m;
     6 int a[N];
     7 int f[M],flag[M];
     8 char st[5];
     9 inline int read(){
    10     int x=0,f=1; char ch=getchar();
    11     while (ch>'9'||ch<'0'){ if (ch=='-') f=-1; ch=getchar(); }
    12     while (ch<='9'&&ch>='0'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }
    13     return x*f;
    14 }
    15 int main(){
    16     n=read(); m=read();
    17     int top=0;
    18     for (int i=1;i<=n;i++){
    19         a[i]=read();
    20         if (!f[a[i]]) f[a[i]]=++top;
    21         a[i]=f[a[i]];
    22     }
    23     for (int i=1;i<=m;i++){
    24         scanf("%s",st);
    25         int x=read(),y=read();
    26         if (st[0]=='Q'){
    27             int ans=0;
    28             for (int j=x;j<=y;j++)
    29                 if (flag[a[j]]!=i) ans++,flag[a[j]]=i;
    30             printf("%d
    ",ans);
    31         } else{
    32             if (!f[y]) f[y]=++top;
    33             a[x]=f[y];
    34         }
    35     }
    36     return 0;
    37 } 
    暴力

    当然我们要去思考一些别的算法

    这道题参考了一下hzw学长

    我们用pre[i]表示前一个和i颜色相同的笔的位置

    询问[l,r]的时候如果pre[i]<l说明这段区间没有和i颜色相同的笔,ans++

    所以对于这段区间,我们可以用分块大法

    对于每一块内的pre值排个序,整个块的查询二分即可

     1 #include<bits/stdc++.h>
     2 #define N 10005
     3 #define M 1000005
     4 using namespace std;
     5 int n,m,blo;
     6 int a[N],b[N],pre[N],t[N];
     7 int last[M];
     8 char st[5];
     9 int read(){
    10     int x=0,f=1; char ch=getchar();
    11     while (ch>'9'||ch<'0'){ if (ch=='-') f=-1; ch=getchar(); }
    12     while (ch<='9'&&ch>='0'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }
    13     return x*f;
    14 }
    15 void reset(int x){
    16     int l=(x-1)*blo+1,r=min(n,x*blo);
    17     for (int i=l;i<=r;i++) pre[i]=t[i];
    18     sort(pre+l,pre+r+1);
    19 }
    20 void build(){
    21     for (int i=1;i<=n;i++){
    22         t[i]=last[a[i]];
    23         last[a[i]]=i;
    24     }
    25     for (int i=1;i<=b[n];i++) reset(i);
    26 }
    27 int find(int x,int k){
    28     int l=(x-1)*blo+1,r=min(n,x*blo);
    29     int st=l;
    30     while (l<=r){
    31         int mid=(l+r)>>1;
    32         if (pre[mid]<k) l=mid+1;
    33                     else r=mid-1;
    34     }
    35     return l-st;
    36 } 
    37 int query(int l,int r){
    38     int ans=0;
    39     if (b[l]==b[r]){
    40         for (int i=l;i<=r;i++)
    41             if (t[i]<l) ans++;
    42     } else{
    43         for (int i=l;i<=b[l]*blo;i++)
    44             if (t[i]<l) ans++;
    45         for (int i=(b[r]-1)*blo+1;i<=r;i++)
    46             if (t[i]<l) ans++;
    47         for (int i=b[l]+1;i<=b[r]-1;i++)
    48             ans+=find(i,l);
    49     }
    50     return ans;
    51 }
    52 void change(int x,int k){
    53     for (int i=1;i<=n;i++) last[a[i]]=0;
    54     a[x]=k;
    55     for (int i=1;i<=n;i++){
    56         int s=t[i];
    57         t[i]=last[a[i]];
    58         last[a[i]]=i;
    59         if (t[i]!=s) reset(b[i]);
    60     }
    61 }
    62 int main(){
    63     n=read(); m=read();
    64     blo=sqrt(n);
    65     for (int i=1;i<=n;i++){
    66         a[i]=read();
    67         b[i]=(i-1)/blo+1;
    68     }
    69     build();
    70     for (int i=1;i<=m;i++){
    71         scanf("%s",st);
    72         int x=read(),y=read();
    73         if (st[0]=='Q') printf("%d
    ",query(x,y));
    74                     else change(x,y);
    75     }
    76     return 0;
    77 } 
    分块
  • 相关阅读:
    网页页面合适的大小
    Spring IO Platform简介及示例
    Spring Boot 单元测试详解+实战教程
    Spring Boot日志集成
    Spring Boot 16 条最佳实践
    Spring Boot自动配置原理、实战
    Spring Boot自动配置
    Windows10 IME占用过高临时解决办法
    GitLab版本管理
    大型系统重构的步骤梳理
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7809895.html
Copyright © 2011-2022 走看看