zoukankan      html  css  js  c++  java
  • P3850 [TJOI2007]书架

    题目描述

    Knuth先生家里有个精致的书架,书架上有N本书,如今他想学到更多的知识,于是又买来了M本不同的新书。现在他要把新买的书依次插入到书架中,他已经把每本书要插入的位置标记好了,并且相应的将它们放好。由于Knuth年龄已大,过几天他已经记不清某些位置上放的到底是什么书了,请问你能帮助他吗?

    输入输出格式

    输入格式:

    输入文件的第一行为整数N,接下来N行分别是书架上依次放着的N本书的书名(书名由不含空格的字符串构成,长度不超过10)。下一行将要输入一个整数M,接下来的M行分别为这本书的书名和要插入的位置。下一行将要输入一个整数Q,接下来共有Q次询问,每行都是一个整数表示询问的位置。(书架上位置的编号从0开始)

    输出格式:

    输出Q行,每行对应着相应查询位置的书名。

    输入输出样例

    输入样例#1: 
    3
    Math
    Algorithm
    Program
    2
    Picture 2
    System 1
    3
    0
    1
    3
    输出样例#1: 
    Math
    System
    Picture

    说明

    原来有三本书Math、Algorithm、System,后来又买了两本书,分别插入到2和1的位置,每次插入时其他书都要向后挪一个位置,最后书架上书的序列为:

    0 Math

    1 System

    2 Algorithm

    3 Picture

    4 Program

    Q次询问依次为0, 1, 3位置的书,所以答案为:Math、System、Picture

    对于30%的数据,1 ≤ N ≤ 100, 1 ≤ M ≤ 103, 1 ≤ Q ≤ 103

    对于100%的数据,1 ≤ N ≤ 200, 1 ≤ M ≤ 105, 1≤Q≤104

    对于100%的数据都符合题目中所描述的限制关系,数据保证每次插入的位置均不超过当时书架上书的数量,而且保证Q次查询中的每个位置上一定有书。

    Solution:

      水题,就一SB平衡树。

      用平衡树维护中序,直接模拟插入的过程,再查询第k位置输出就好了。

    代码:

    /*Code by 520 -- 10.3*/
    #include<bits/stdc++.h>
    #define il inline
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    using namespace std;
    const int N=200005;
    int n,m,ch[N][2],root,cnt,siz[N],date[N],rnd[N];
    string s[N];
    il int newnode(int v){siz[++cnt]=1,date[cnt]=v,rnd[cnt]=rand();return cnt;}
    il void up(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
    int merge(int x,int y){
        if(!x||!y) return x+y;
        if(rnd[x]<rnd[y]) {ch[x][1]=merge(ch[x][1],y),up(x);return x;} 
        else {ch[y][0]=merge(x,ch[y][0]),up(y);return y;}
    }
    void split(int rt,int v,int &x,int &y){
        if(!rt) {x=y=0;return;}
        if(siz[ch[rt][0]]<v) x=rt,split(ch[rt][1],v-siz[ch[rt][0]]-1,ch[x][1],y),up(x);
        else y=rt,split(ch[rt][0],v,x,ch[y][0]),up(y);    
    }
    il int kth(int rt,int v){
        while(1){
            if(siz[ch[rt][0]]>=v) rt=ch[rt][0];
            else if(siz[ch[rt][0]]+1<v) v-=siz[ch[rt][0]]+1,rt=ch[rt][1];
            else return date[rt];
        }
    }
    int main(){
        ios::sync_with_stdio(0);
        cin>>n; int v,x,y;
        For(i,1,n) cin>>s[i],root=merge(root,newnode(i));
        cin>>m;
        For(i,n+1,n+m) cin>>s[i]>>v,split(root,v,x,y),root=merge(merge(x,newnode(i)),y);
        cin>>m;
        For(i,1,m) cin>>v,split(root,v,x,y),cout<<s[kth(y,1)]<<endl,root=merge(x,y);
        return 0;    
    }
  • 相关阅读:
    SQL语法:查询此表有另外一个表没有的数据
    .NET平台开源项目速览-最快的对象映射组件Tiny Mapper之项目实践
    win7 64 安装Oracle 11G 、使用PLSQL进行连接 标准实践
    json 筛选数据 $.grep过滤数据
    bootstrap table 行号 显示行号 添加行号 bootstrap-table 行号
    ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践
    JS中判断JSON数据是否存在某字段的方法 JavaScript中判断json中是否有某个字段
    json 数字key json 数字作为主键
    ajax 跨域 headers JavaScript ajax 跨域请求 +设置headers 实践
    扩展:gridview 空数据时显示表头
  • 原文地址:https://www.cnblogs.com/five20/p/9792008.html
Copyright © 2011-2022 走看看