题目描述
Knuth先生家里有个精致的书架,书架上有N本书,如今他想学到更多的知识,于是又买来了M本不同的新书。现在他要把新买的书依次插入到书架中,他已经把每本书要插入的位置标记好了,并且相应的将它们放好。由于Knuth年龄已大,过几天他已经记不清某些位置上放的到底是什么书了,请问你能帮助他吗?
输入输出格式
输入格式:
输入文件的第一行为整数N,接下来N行分别是书架上依次放着的N本书的书名(书名由不含空格的字符串构成,长度不超过10)。下一行将要输入一个整数M,接下来的M行分别为这本书的书名和要插入的位置。下一行将要输入一个整数Q,接下来共有Q次询问,每行都是一个整数表示询问的位置。(书架上位置的编号从0开始)
输出格式:
输出Q行,每行对应着相应查询位置的书名。
输入输出样例
说明
原来有三本书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^5, 1 ≤ 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 ",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 }