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;
    }
  • 相关阅读:
    ABAP接口用法
    监听textarea数值变化
    The first step in solving any problem is recognizing there is one.
    Wrinkles should merely indicate where smiles have been.
    God made relatives.Thank God we can choose our friends.
    Home is where your heart is
    ABAP跳转屏幕
    Python 工具包 werkzeug 初探
    atom通过remote ftp同步本地文件到远程主机的方法
    Mongodb学习笔记一
  • 原文地址:https://www.cnblogs.com/cytus/p/9606921.html
Copyright © 2011-2022 走看看