洛谷P3850 书架

题目描述

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 ≤ 10^3, 1 ≤ Q ≤ 10^3

对于100%的数据,1 ≤ N ≤ 200, 1 ≤ M ≤ 10^51 ≤ Q ≤ 10^4

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

__________________________________________________________________________________

FHQ_TREAP

__________________________________________________________________________________

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e5+300;
  4 char s[maxn][12];
  5 int n,m,q;
  6 struct node
  7 {
  8     int ch[2],siz,rd,val;
  9 }tr[maxn];
 10 int tot,root;
 11 int newnode(int x)
 12 {
 13     tot++;
 14     tr[tot].siz=1;
 15     tr[tot].rd=rand();
 16     tr[tot].val=x;
 17     tr[tot].ch[1]=tr[tot].ch[0]=0;
 18     return tot;
 19 }
 20 void update(int cur)
 21 {
 22     tr[cur].siz=tr[tr[cur].ch[0]].siz+tr[tr[cur].ch[1]].siz+1;
 23 }
 24 int merge(int x,int y)
 25 {
 26     if(x*y==0)return x+y;
 27     if(tr[x].rd<tr[y].rd)
 28     {
 29         tr[x].ch[1]=merge(tr[x].ch[1],y);
 30         update(x);
 31         return x;
 32     }
 33     else
 34     {
 35         tr[y].ch[0]=merge(x,tr[y].ch[0]);
 36         update(y);
 37         return y;
 38     }
 39 }
 40 void split(int cur,int k,int &x,int &y)
 41 {
 42     if(!cur)x=y=0;
 43     else
 44     {
 45         if(k>tr[tr[cur].ch[0]].siz)
 46         {
 47             x=cur;
 48             split(tr[cur].ch[1],k-tr[tr[cur].ch[0]].siz-1,tr[cur].ch[1],y);
 49         }
 50         else 
 51         {
 52             y=cur;
 53             split(tr[cur].ch[0],k,x,tr[cur].ch[0]);
 54         }
 55         update(cur);
 56     }
 57 }
 58 int kth(int now,int k)
 59 {
 60     int cur=now;
 61     while(cur)
 62     {
 63         if(tr[tr[cur].ch[0]].siz+1==k)return tr[cur].val;
 64         else if(tr[tr[cur].ch[0]].siz>=k)cur=tr[cur].ch[0];
 65         else 
 66         {
 67             k-=tr[tr[cur].ch[0]].siz+1;
 68             cur=tr[cur].ch[1];
 69         }
 70     }
 71 }
 72 void insert(int v,int p)
 73 {
 74     int x,y;
 75     split(root,p-1,x,y);
 76     root=merge(merge(x,newnode(v)),y);
 77 }
 78 void print(int p)
 79 {
 80     printf("%s\n",s[kth(root,p)]);
 81 }
 82 int main()
 83 {
 84     srand((unsigned)time(0));
 85     scanf("%d",&n);
 86     for(int i=1;i<=n;++i)
 87     {
 88         scanf("%s",s[i]);
 89         root=merge(root,newnode(i));
 90     }
 91     scanf("%d",&m);
 92     int p;
 93     for(int i=n+1;i<=n+m;++i)
 94     {
 95         scanf("%s%d",s[i],&p);
 96         insert(i,p+1);
 97     }
 98     scanf("%d",&q);
 99     for(int i=0;i<q;++i)
100     {
101         scanf("%d",&p);
102         print(p+1);
103     }
104     return 0;
105 }
View Code

 

posted on 2019-03-28 20:49  gryzy  阅读(177)  评论(0编辑  收藏  举报

导航