zoukankan      html  css  js  c++  java
  • 【BZOJ2473/2120】维护队列 分块+二分

    Description

    你小时候玩过弹珠吗?
    小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。

    Input

    输入文件第一行包含两个整数N和M。
    第二行N个整数,表示初始队列中弹珠的颜色。
    接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。

    Output

    对于每个Q操作,输出一行表示询问结果。

    Sample Input


    2 3
    1 2
    Q 1 2
    R 1 2
    Q 1 2

    Sample Output

    2
    1

    HINT

    对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。

    Source

    2011福建集训

     惭愧,又看了黄学长题解。。。引入一个pre数组,记录前一个相同颜色的位置,块内排序,有点像一个链?,然后查询时只要比pre【i】比l小,则同一个块内前面的都满足。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cmath>
     6 #define N 10010 
     7 using namespace std;
     8 int last[1000100],pre[N],a[N],b[N],pos[N];
     9 int n,m,q,block;
    10 void build()
    11 {
    12     for (int i=1;i<=n;i++)
    13     {
    14         b[i]=last[a[i]];
    15         last[a[i]]=i;
    16         pos[i]=(i-1)/block+1;
    17     }
    18 }
    19 void make_block(int x)
    20 {
    21     int l=(x-1)*block+1,r=min(x*block,n);
    22     for (int i=l;i<=r;i++)    pre[i]=b[i];
    23     sort(pre+l,pre+r+1);
    24 }
    25 int er_find(int x,int v)
    26 {
    27     int l=(x-1)*block+1,r=min(x*block,n),l1;
    28     l1=l;
    29     while (l<=r)
    30     {
    31         int mid=(l+r)>>1;
    32         if (pre[mid]<v) l=mid+1;
    33         else r=mid-1;
    34     }
    35     return l-l1;
    36 }
    37 int query(int l,int r)
    38 {
    39     int ans=0;
    40     if (pos[l]==pos[r]) {for (int i=l;i<=r;i++) if (b[i]<l) ans++;}
    41     else    
    42     {
    43         for (int i=l;i<=pos[l]*block;i++) if (b[i]<l) ans++;
    44         for (int i=(pos[r]-1)*block+1;i<=r;i++) if (b[i]<l) ans++;
    45         for (int i=pos[l]+1;i<pos[r];i++)    ans+=er_find(i,l);
    46     }
    47     return ans;
    48 }
    49 void change(int x,int v)
    50 {
    51     for (int i=1;i<=n;i++) last[a[i]]=0;
    52     a[x]=v;
    53     for (int i=1;i<=n;i++)
    54     {
    55         int t=b[i];
    56         b[i]=last[a[i]];
    57         if (t!=b[i])    make_block(pos[i]);
    58         last[a[i]]=i;
    59     }
    60 }
    61 int main()
    62 {
    63     scanf("%d%d",&n,&q);
    64     for (int i=1;i<=n;i++)    scanf("%d",&a[i]);
    65     block=int(sqrt(n));
    66     if (n%block) m=n/block+1;
    67     else    m=n/block;
    68     build();
    69     for (int i=1;i<=m;i++) make_block(i);
    70     for (int i=1;i<=q;i++)
    71     {
    72         char ch[5];
    73         int x,y;
    74         scanf("%s%d%d",ch,&x,&y);
    75         if (ch[0]=='Q')    printf("%d
    ",query(x,y));
    76         else    change(x,y);
    77     }
    78     return 0;
    79 } 
    View Code
    —Anime Otaku Save The World.
  • 相关阅读:
    【leetcode_easy_array】1010. Pairs of Songs With Total Durations Divisible by 60
    【leetcode_easy_array】1013. Partition Array Into Three Parts With Equal Sum
    【leetcode_easy_array】1122. Relative Sort Array
    【opencv基础】opencv中cv::Mat和eigen数据之间的转换
    【c++基础】测试SocketCAN的收发功能
    SRM系统与ERP系统之间存在什么联系(转)
    使用IDEA搭建一个简单的SpringBoot项目——详细过程(转)
    SpringBoot(一):使用IDEA快速搭建一个SpringBoot项目(详细)
    IntelliJ IDEA创建maven web项目(IDEA新手适用)(转)
    Maven的安装与配置(转)
  • 原文地址:https://www.cnblogs.com/DMoon/p/5259552.html
Copyright © 2011-2022 走看看