1 /****************************************************
 2 题目: Black Box(poj 1442)
 3 链接: http://poj.org/problem?id=1442
 4 题意: 给n个数,m个询问,对第i数个询问前Xi个数中第
 5         i小的是那个数。
 6 算法: treap树
 7 *****************************************************/
 8 #include<iostream>
 9 #include<algorithm>
10 #include<cstdio>
11 #include<cstring>
12 #include<cstdlib>
13 using namespace std;
14 
15 typedef struct Node
16 {
17     Node *l,*r;
18     int val,pri;   ///val当前节点的值,pri当前节点的优先级
19     int sz;        ///子树的节点数
20     Node(int x)    ///构造函数初始化
21     {
22         l=r=NULL;
23         pri=rand();
24         val=x;
25         sz=1;
26     }
27 }Node;
28 Node *root;   ///根节点
29 
30 int getsz(Node *T)   ///求子树的节点数
31 {
32     if (T==NULL) return 0;
33     return T->sz;
34 }
35 
36 Node *L_rotate(Node *T) ///右节点的优先级大于当前节点,进行左旋转
37 {                       
38     Node *A=T->r;
39     T->r=A->l;
40     A->l=T;
41     A->sz=T->sz;
42     T->sz=getsz(T->l)+getsz(T->r)+1; ///T->l可能为空,要用getsz函数
43     return A;
44 }
45 Node *R_rotate(Node *T)   ///左节点的优先级大于当前节点,进行右旋转
46 {
47     Node *A=T->l;
48     T->l=A->r;
49     A->r=T;
50     A->sz=T->sz;
51     T->sz=getsz(T->l)+getsz(T->r)+1;
52     return A;
53 }
54 void inser(Node *&T,int val) ///插入函数,和二叉排序树差不多,多了个优先级的改变
55 {
56     if (T==NULL)
57     {
58         T=new Node(val);
59         return ;
60     }
61     T->sz++;
62     if (T->val>=val)
63     {
64         inser(T->l,val);
65         if ((T->l->pri)<(T->pri)) T=R_rotate(T); ///判断优先级并旋转
66     }
67     else
68     {
69         inser(T->r,val);
70         if ((T->r->sz)<(T->pri)) T=L_rotate(T);
71     }
72 }
73 int Find(Node *T,int k)  ///查找函数
74 {
75     int temp=getsz(T->l)+1;
76     if (temp==k) return T->val;
77     if (temp>k) return Find(T->l,k);
78     return Find(T->r,k-temp);
79 }
80 
81 int a[100005];
82 
83 int main()
84 {
85      int n,m;
86      root=NULL;
87      scanf("%d%d",&n,&m);
88      for (int i=1;i<=n;i++) scanf("%d",&a[i]);
89      int j=1;
90      for (int i=1;i<=m;i++)
91      {
92          int x;
93          scanf("%d",&x);
94          for (;j<=x;j++) inser(root,a[j]);
95          printf("%d\n",Find(root,i));
96      }
97 }

 

posted on 2016-08-13 11:06  pb2016  阅读(737)  评论(0编辑  收藏  举报