• 书架


    题目描述

    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 ≤ 10^5105, 1 ≤ Q ≤ 10^41Q104

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

    思路:无旋treap维护中序。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include<bits/stdc++.h>
    #define REP(i, a, b) for(int i = (a); i <= (b); ++ i)
    #define REP(j, a, b) for(int j = (a); j <= (b); ++ j)
    #define PER(i, a, b) for(int i = (a); i >= (b); -- i)
    using namespace std;
    const int maxn=1e6+5;
    template <class T>
    inline void rd(T &ret){
        char c;
        ret = 0;
        while ((c = getchar()) < '0' || c > '9');
        while (c >= '0' && c <= '9'){
            ret = ret * 10 + (c - '0'), c = getchar();
        }
    }
    int n,m,q,root,tot,bg[maxn],p[maxn][2],rnd[maxn],dt[maxn],tmp;
    string s[maxn];
    void pushup(int hd){
          bg[hd]=bg[p[hd][0]]+bg[p[hd][1]]+1;
          return;
    }
    int newnode(int cur){
         bg[++tot]=1,dt[tot]=cur,rnd[tot]=rand();
         return tot;
    }
    int mg(int x,int y){
        if(!x||!y)return x+y;
        if(rnd[x]<rnd[y]){
             p[x][1]=mg(p[x][1],y);
             pushup(x);
             return x;
        }
        else{
            p[y][0]=mg(x,p[y][0]);
            pushup(y);
            return y;
        }
    }
    void split(int rt,int v,int &x,int &y){
         if(!rt){
             x=y=0;
             return;
         }
         if(bg[p[rt][0]]<v)x=rt,split(p[rt][1],v-bg[p[rt][0]]-1,p[rt][1],y),pushup(x);
         else y=rt,split(p[rt][0],v,x,p[rt][0]),pushup(y);
    }
    int kth(int rt,int v){
          while(true){
              if(bg[p[rt][0]]>=v)rt=p[rt][0];
              else if(bg[p[rt][0]]+1<v)v-=bg[p[rt][0]]+1,rt=p[rt][1];
              else return dt[rt];
          }
    }
    int main(){
        rd(n);
        int k,x,y;
        REP(i,1,n)cin>>s[i],root=mg(root,newnode(i));
        rd(m);
        REP(i,n+1,n+m)cin>>s[i]>>tmp,split(root,tmp,x,y),root=mg(mg(x,newnode(i)),y);
        rd(m);
        REP(i,1,m)cin>>tmp,split(root,tmp,x,y),cout<<s[kth(y,1)]<<endl,root=mg(x,y);
        return 0;
    }
  • 相关阅读:
    网上搜的逆元知识
    关于树的一点学习【清北学堂】
    矩阵乘法和斐波那契数列【清北学堂】
    Luogu【P1130】红牌(DP)
    Luogu【P1901】发射站(单调栈)
    Oracle_PL/SQL(1) 匿名块
    Oracle_SQL(7) 复杂查询
    Oracle_SQL(6) 单行函数
    Oracle_SQL(5) 连接和子查询
    Oracle_SQL(4) DDL 表和约束
  • 原文地址:https://www.cnblogs.com/czy-power/p/10391785.html
Copyright © 2020-2023  润新知