【模板】可持久化线段树 1(主席树)

题目背景

这是个非常经典的主席树入门题——静态区间第K小

数据已经过加强,请使用主席树。同时请注意常数优化

题目描述

如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值。

输入格式

第一行包含两个正整数N、M,分别表示序列的长度和查询的个数。

第二行包含N个整数,表示这个序列各项的数字。

接下来M行每行包含三个整数l, r, kl,r,k , 表示查询区间[l, r][l,r]内的第k小值。

输出格式

输出包含k行,每行1个整数,依次表示每一次查询的结果

输入输出样例

输入 #1

5 5
25957 6405 15770 26287 26465 
2 2 1
3 4 1
4 5 1
1 2 2
4 4 1

输出 #1

6405
15770
26287
25957
26287

样例数据说明:

N=5,数列长度为5,数列从第一项开始依次为[25957, 6405, 15770, 26287, 26465 ]

第一次查询为[2, 2]区间内的第一小值,即为6405

第二次查询为[3, 4]区间内的第一小值,即为15770

第三次查询为[4, 5]区间内的第一小值,即为26287

第四次查询为[1, 2]区间内的第二小值,即为25957

第五次查询为[4, 4]区间内的第一小值,即为26287

 

分析:

模板题???去TM的。。。一道模板题调我一晚上。。。(除了treap,树剖外调的时间最长一道题目)

 

PS:目前调(不含第一遍写的时间)的时间最久的(不看题解):

1.猪国杀??? 1个月 (还没写好。。。)

2.treap 4个小时

2.树剖 4个小时

4.主席树 3个小时

4.有机化学之神之偶尔会作弊 3个小时(神题。。。结合多种算法。。)

6.网络流 2.5个小时

7.字符串的展开 2个小时

7.牛绣花(你TM试试自己推这题的公式。。。) 2个小时

9.洛谷P1962 斐波那契数列(哼哼,你自己看看数据范围) 1.5小时

9.[AHOI2009]中国象棋(你试试这题递推方程。。。) 1.5小时

 

 

 

CODE:

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 const int M=30000005;
 6 int p[M],a[M];
 7 int n,m;
 8 int rt[M],tot;
 9 struct tree{
10     int son[2],size;
11 }node[M];
12 void build (int &rt,int l,int r){
13     rt=++tot;
14     int mid=(l+r)>>1;
15     if (!(l^r)) return ;
16     build (node[rt].son[0],l,mid);
17     build (node[rt].son[1],mid+1,r);
18 }
19 int bsearch(int k){
20     int l=1,r=m;
21     while (l<=r){
22         int mid=(l+r)>>1;
23         if (p[mid]==k) return mid;
24         if (p[mid]<k) l=mid+1;
25         else r=mid-1;
26     }
27     return l;
28 }
29 void np(int &rt,int lst,int l,int r,int val){
30     node[rt=++tot]=node[lst];
31     ++node[rt].size;
32     int mid=(l+r)>>1;
33     if (!(l^r)) return ;
34     if (val<=mid) np(node[rt].son[0],node[lst].son[0],l,mid,val);
35     else np(node[rt].son[1],node[lst].son[1],mid+1,r,val);
36 }
37 int query(int rt1,int rt2,int l,int r,int k){
38     int mid=(l+r)>>1;
39     if (!(l^r)) return p[l];
40     if(node[node[rt2].son[0]].size-node[node[rt1].son[0]].size>=k) 
41         return  query(node[rt1].son[0],node[rt2].son[0],l,mid,k); 
42     else
43         return  query(node[rt1].son[1], node[rt2].son[1],mid+1,r,k-node[node[rt2].son[0]].size+node[node[rt1].son[0]].size); 
44 }
45 int read(){
46     int res=0;
47     int f=1;
48     char c=getchar();
49     while (c>'9'||c<'0') {
50         if (c=='-') f=-1;
51         c=getchar();
52     }
53     while (c<='9'&&c>='0') {
54         res=(res<<3)+(res<<1)+c-'0';
55         c=getchar();
56     }
57     return res*f;
58 }
59 int main(){
60     scanf ("%d",&n);
61     int mm;
62     scanf ("%d",&mm);
63     for (int i=1;i<=n;i++)
64         a[i]=read(),p[i]=a[i];
65     sort(p+1,p+n+1);
66     m=unique(p+1,p+n+1)-p-1;
67     build(rt[0],1,m);
68     //cout<<m<<endl;
69     /*for (int i=1;i<=m;i++)
70         cout<<p[i]<<endl;*/
71     for (int i=1;i<=n;i++){
72         //cout<<a[i]<<" "<<bsearch(a[i])<<endl;
73         np(rt[i],rt[i-1],1,m,bsearch(a[i]));
74     }
75     while (mm--){
76         int i,j,l;
77         i=read(),j=read(),l=read();
78         printf("%d\n",query(rt[i-1],rt[j],1,m,l));
79     }
80     //system("pause");
81     return 0;
82 }

 

 

 

 

posted @ 2019-07-28 16:59  Sword_Art_Online  阅读(180)  评论(0编辑  收藏  举报