• fhqtreap


    [SDOI2008]郁闷的小JJ

    题目描述

    小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的书共多少本。

    输出格式:

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

    输入输出样例

    如果输入了
    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
    0
    2

    说明

    对于100%的数据,1<=N,M<=100000
    对于100%的数据,所有出现的书的编码为不大于2147483647的正数。


    treap大模板题
    (话说这样的题目都只能是模板题吧)
    先把书编码离散化
    对每一种书都种一棵treap 这对array选手不友好啊
    之后还是熟悉的操作
    代码蒯上

    #include<iostream>
    #include<iomanip>
    #include<cmath>
    #include<map>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int gotcha()
    {
        register int _a=0;bool _b=1;register char _c=getchar();
        while(_c<'0' || _c>'9'){if(_c=='-')_b=0;_c=getchar();}
        while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
        return _b?_a:-_a;
    }
    #define ml make_pair
    const int _ = 100002;int seed=19260817;
    inline int ou(){return seed=seed*47281ll%2147483647;}
    typedef struct node* point;
    point null;
    struct node
    {
        int rn,sz,d;
        point lc,rc;
        node(int got){d=got,rn=ou(),sz=1,lc=rc=null;}
        inline void up(){sz=lc->sz+rc->sz+1;}
        inline void del(){if(this!=null)lc->del(),rc->del(),delete this;}
    };
    point root[_];int bk[_],lmp=0,m,n;
    map<int,int> mp;
    inline point merge(point a,point b)
    {
        if(a==null)return b;if(b==null)return a;
        if(a->rn<b->rn){a->rc=merge(a->rc,b),a->up();return a;}
        else{b->lc=merge(a,b->lc),b->up();return b;}
    }
    inline pair<point,point> split(point now,int num)
    {
        if(now==null)return ml(null,null);
        point lc=now->lc,rc=now->rc;
        if(now->lc->sz==num){now->lc=null,now->up();return ml(lc,now);}
        if(now->lc->sz+1==num){now->rc=null,now->up();return ml(now,rc);}
        if(num<now->lc->sz)
        {
            pair<point,point> T=split(now->lc,num);
            now->lc=T.second,now->up();
            return ml(T.first,now);
        }
        else
        {
            pair<point,point> T=split(now->rc,num-now->lc->sz-1);
            now->rc=T.first,now->up();
            return ml(now,T.second);
        }
    }
    int time_finder(int kind,int num)
    {
        int s=0,t=2e9;point now=root[kind];
        while(now!=null)
        {
            if(num==now->d)t=min(t,s+now->lc->sz+1);
            if(num<=now->d)now=now->lc;
            else s+=now->lc->sz+1,now=now->rc;
        }
        return t==2e9?s:t;
    }
    void insert(int num){if(mp.find(num)==mp.end())mp[num]=++lmp;}
    int main()
    {
        mp.clear();
        register int i,j,k;register char op;
        n=gotcha(),m=gotcha();
        null=new node(0),null->sz=0;
        for(i=0;i<_;i++)root[i]=null;
        for(i=1;i<=n;i++)
        {
            j=gotcha();
            insert(j),bk[i]=mp[j],root[bk[i]]=merge(root[bk[i]],new node(i));
        }
        while(m--)
        {
            op=getchar();while(op!='C' && op!='Q')op=getchar();
            if(op=='Q')
            {
                i=gotcha()-1,j=gotcha(),k=gotcha();
                insert(k),k=mp[k];
                printf("%d
    ",time_finder(k,j)-time_finder(k,i));
            }
            else
            {
                i=gotcha(),k=bk[i];
                pair<point,point> a,b;
                a=split(root[k],time_finder(k,i)-1),b=split(a.second,1);
                delete b.first;
                root[k]=merge(a.first,b.second);
                k=gotcha(),insert(k);
                bk[i]=mp[k],k=mp[k];
                a=split(root[k],time_finder(k,i));
                root[k]=merge(a.first,merge(new node(i),a.second));
            }
        }
        for(i=0;i<_;i++)root[i]->del();delete null;
        return 0;
    }
    
  • 相关阅读:
    五、批量插入
    四、操作BLOB类型字段
    三、使用PreparedStatement实现CRUD操作
    二、获取数据库连接
    一、JDBC概述
    最短平均码长(挑出假硬币问题的解法)
    信息量和信息熵
    洛谷P2114
    Servlet续(HttpServletRequest类和HttpServletResponse类)
    Servlet
  • 原文地址:https://www.cnblogs.com/finder-iot/p/7601250.html
Copyright © 2020-2023  润新知