zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      题目传送门

    郁闷的小j

    题目描述

    小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架。虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他面临着被解雇的危险,这也正是他所郁闷的。

    具体说来,书架由N个书位组成,编号从1到N。每个书位放着一本书,每本书有一个特定的编码。

    小J的工作有两类:

    1.图书馆经常购置新书,而书架任意时刻都是满的,所以只得将某位置的书拿掉并换成新购的书。

    2.小J需要回答顾客的查询,顾客会询问某一段连续的书位中某一特定编码的书有多少本。

    例如,共5个书位,开始时书位上的书编码为1,2,3,4,5

    一位顾客询问书位1到书位3中编码为“2”的书共多少本,得到的回答为:1

    一位顾客询问书位1到书位3中编码为“1”的书共多少本,得到的回答为:1

    此时,图书馆购进一本编码为“1”的书,并将它放到2号书位。

    一位顾客询问书位1到书位3中编码为“2”的书共多少本,得到的回答为:0

    一位顾客询问书位1到书位3中编码为“1”的书共多少本,得到的回答为:2

    ……

    你的任务是写一个程序来回答每个顾客的询问。

    输入输出格式

    输入格式:

     

    第一行两个整数N,M,表示一共N个书位,M个操作。

    接下来一行共N个整数数A1,A2…AN,Ai表示开始时位置i上的书的编码。

    接下来M行,每行表示一次操作,每行开头一个字符

    若字符为‘C’,表示图书馆购进新书,后接两个整数A(1<=A<=N),P,表示这本书被放在位置A上,以及这本书的编码为P。

    若字符为‘Q’,表示一个顾客的查询,后接三个整数A,B,K(1<=A<=B<=N),表示查询从第A书位到第B书位(包含A和B)中编码为K的书共多少本。

     

    输出格式:

     

    对每一个顾客的查询,输出一个整数,表示顾客所要查询的结果。

     

    输入输出样例

    输入样例#1: 
    5 5
    1 2 3 4 5
    Q 1 3 2
    Q 1 3 1
    C 2 1
    Q 1 3 2
    Q 1 3 1
    
    输出样例#1: 
    1
    1
    0
    2
    

    说明

    对于40%的数据,1<=N,M<=5000

    对于100%的数据,1<=N,M<=100000

    对于100%的数据,所有出现的书的编码为不大于2147483647的正数。


      分析:

      没错,这是一道$Splay$裸题,但是这里用分快来做。

      这题和那道教主的魔法做法基本一样,只是稍有变化。另外,这题数据范围特别大,分块的做法需要吸一口氧气。

      Code:

      

    //It is made by HolseLee on 7th Sep 2018
    //Luogu.org P2464
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    const int N=1e5+7;
    int n,m,a[N],b[N],belong[N],l[N],r[N],tot,siz;
    
    inline int read()
    {
        char ch=getchar(); int num=0; bool flag=false;
        while( ch<'0' || ch>'9' ) {
            if( ch=='-' ) flag=true; ch=getchar();
        }
        while( ch>='0' &&  ch<='9' ) {
            num=num*10+ch-'0'; ch=getchar();
        }
        return flag ? -num : num;
    }
    
    inline void reset(int x)
    {
        for(int i=l[x]; i<=r[x]; ++i) b[i]=a[i];
        sort(b+l[x],b+r[x]+1);
    }
    
    void build()
    {
        siz=sqrt(n); tot=n/siz; if( n%siz ) tot++;
        for(int i=1; i<=n; ++i) belong[i]=(i-1)/siz+1;
        for(int i=1; i<=tot; ++i) l[i]=(i-1)*siz+1, r[i]=i*siz;
        r[tot]=n;
        for(int i=1; i<=tot; ++i) sort(b+l[i],b+r[i]+1);
    }
    
    inline void update(int pos,int v)
    {
        a[pos]=v;
        reset(belong[pos]);
    }
    
    inline int quary(int x,int y,int z)
    {
        int ret=0;
        if( belong[x]==belong[y] ) {
            for(int i=x; i<=y; ++i) ret+=(a[i]==z);
            return ret;
        }
        for(int i=x; i<=r[belong[x]]; ++i) ret+=(a[i]==z);
        for(int i=l[belong[y]]; i<=y; ++i) ret+=(a[i]==z);
        int L,R;
        for(int i=belong[x]+1; i<belong[y]; ++i) {
            L=lower_bound(b+l[i],b+r[i]+1,z)-b;
            R=lower_bound(b+l[i],b+r[i]+1,z+1)-b;
            ret+=(R-L);
        }
        return ret;
    }
    
    int main()
    {
        n=read(); m=read();
        for(int i=1; i<=n; ++i) a[i]=read(), b[i]=a[i];
        build();
        char opt[3]; int x,y,z;
        for(int i=1; i<=m; ++i) {
            scanf("%s",opt);
            x=read(), y=read();
            if( opt[0]=='Q' ) {
                z=read();
                printf("%d
    ",quary(x,y,z));
            } else {
                update(x,y);
            }
        }
        return 0;
    }
  • 相关阅读:
    使用EFCore连接现有数据库
    C#面试题总结
    xamarin学习--发布apk安装包
    xamarin学习--导航参数注意事项
    centos8 安装 gitlab
    mvc添加全局过滤器
    Windows平台查看端口占用情况
    asp.net core cli---创建一个不启用https的项目
    asp.net core cli
    启动nuxt项目报错WARN node unsupported "node@v8.9.3" is incompatible with chalk@^4.1.0, expec...
  • 原文地址:https://www.cnblogs.com/cytus/p/9606921.html
Copyright © 2011-2022 走看看