主席树

 1 /*
 2   题意:查询区间第K大
 3   题解:主席树
 4   时间:
 5 */
 6 
 7 #include <bits/stdc++.h>
 8 using namespace std;
 9 
10 typedef long long LL;
11 const int MAXN = 100005;
12 const LL MOD7 = 1e9+7;
13 
14 struct TreeNode
15 {
16     int sum;
17     int lson,rson;
18 }tree[MAXN<<5];
19 int cnt;
20 
21 int root[MAXN],a[MAXN],num[MAXN];
22 int n,Q;
23 
24 int newNode(int sum,int lson,int rson)
25 {
26     ++cnt;
27     tree[cnt].sum=sum;
28     tree[cnt].lson=lson;
29     tree[cnt].rson=rson;
30     return cnt;
31 }
32 
33 void Insert(int &root,int pre,int pos,int L,int R)
34 {
35     root=newNode(tree[pre].sum+1,tree[pre].lson,tree[pre].rson);
36     if (L==R) return;
37     int mid=(L+R)/2;
38     if (pos<=mid) Insert(tree[root].lson,tree[pre].lson,pos,L,mid);
39     else Insert(tree[root].rson,tree[pre].rson,pos,mid+1,R);
40 }
41 
42 int query(int S,int E,int L,int R,int K)
43 {
44     if (L==R) return L;
45     int sum = tree[tree[E].lson].sum-tree[tree[S].lson].sum;
46     int mid=(L+R)/2;
47     if (K<=sum) return query(tree[S].lson,tree[E].lson,L,mid,K);
48     else return query(tree[S].rson,tree[E].rson,mid+1,R,K-sum);
49 }
50 
51 int main()
52 {
53 #ifndef ONLINE_JUDGE
54     freopen("test.txt","r",stdin);
55 #endif // ONLINE_JUDGE
56     int Case;
57     scanf("%d",&Case);
58     while (Case--)
59     {
60         scanf("%d%d",&n,&Q);
61         for (int i=1;i<=n;++i)
62         {
63             scanf("%d",&a[i]);
64             num[i]=a[i];
65         }
66         sort(num+1,num+1+n);
67         int nums=unique(num+1,num+1+n)-(num+1);
68         root[0]=0;cnt=0;
69         for (int i=1;i<=n;++i)
70         {
71             int pos=lower_bound(num+1,num+1+nums,a[i]) - (num+1) + 1;
72             // printf("pos=%d\n",pos);
73             Insert(root[i],root[i-1],pos,1,n);
74         }
75         int x,y,K;
76         for (int i=1;i<=Q;++i)
77         {
78             scanf("%d%d%d",&x,&y,&K);
79             printf("%d\n",num[query(root[x-1],root[y],1,n,K)]);
80         }
81     }
82     return 0;
83 }

 

转载于:https://www.cnblogs.com/LeeSongt/p/9348018.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值