没什么好说的,和2104差不多,写个SBT模板直接套
#include
<
iostream
>
#include
<
algorithm
>
using
namespace
std;
#define
MAXN 100001
int
a[MAXN],n,m;
int
key[
3
*
MAXN],lc[
3
*
MAXN],rc[
3
*
MAXN],sz[
3
*
MAXN],root,cnt;
struct
Query{
int
x,y,tag,k;
}query[
50001
];
int
ans[
50001
];
//////////////////////////////
/
int
search(
int
t,
int
v);
//
返回下标
void
insert(
int
&
t,
int
v);
//
修改了树的结构,故参数需引用
int
deletion(
int
&
t,
int
v);
//
返回下标
int
pred(
int
t,
int
v);
//
返回下标
int
succ(
int
t,
int
v);
//
返回下标
int
select(
int
t,
int
k);
//
返回下标
int
rank(
int
t,
int
v);
//////////////////////////////
void
RightRotate(
int
&
t){
int
k
=
lc[t];
lc[t]
=
rc[k];
rc[k]
=
t;
sz[k]
=
sz[t];
sz[t]
=
sz[lc[t]]
+
sz[rc[t]]
+
1
;
t
=
k;
}
void
LeftRotate(
int
&
t){
int
k
=
rc[t];
rc[t]
=
lc[k];
lc[k]
=
t;
sz[k]
=
sz[t];
sz[t]
=
sz[lc[t]]
+
sz[rc[t]]
+
1
;
t
=
k;
}
int
search(
int
t,
int
v){
if
(
!
t
||
v
==
key[t])
return
t;
if
(v
<
key[t])
return
search(lc[t],v);
else
return
search(rc[t],v);
}
void
Maintain(
int
&
t,
bool
RightDeeper){
//
注意右旋的条件是左子树存在,左旋的条件是右子树存在
if
(
!
RightDeeper){
if
(lc[t]
&&
sz[lc[lc[t]]]
>
sz[rc[t]])
RightRotate(t);
else
if
(lc[t]
&&
rc[lc[t]]
&&
sz[rc[lc[t]]]
>
sz[rc[t]]){
LeftRotate(lc[t]);
RightRotate(t);
}
else
return
;
}
else
{
if
(rc[t]
&&
sz[rc[rc[t]]]
>
sz[lc[t]])
LeftRotate(t);
else
if
(rc[t]
&&
lc[rc[t]]
&&
sz[lc[rc[t]]]
>
sz[lc[t]]){
RightRotate(rc[t]);
LeftRotate(t);
}
else
return
;
}
Maintain(lc[t],
false
);
Maintain(rc[t],
true
);
Maintain(t,
false
);
Maintain(t,
true
);
}
void
insert(
int
&
t,
int
v){
if
(
!
t){
++
cnt;
t
=
cnt;
key[t]
=
v;
lc[t]
=
0
;
rc[t]
=
0
;
sz[t]
=
1
;
return
;
}
sz[t]
++
;
if
(v
<
key[t])
insert(lc[t],v);
else
insert(rc[t],v);
Maintain(t,v
>=
key[t]);
}
int
deletion(
int
&
t,
int
v){
//
如果树中没有一个这样的结点,删除搜索到的最后一个结点并返回其指针
if
(
!
t)
return
0
;
sz[t]
--
;
if
(v
==
key[t]
||
v
<
key[t]
&&!
lc[t]
||
v
>
key[t]
&&!
rc[t]){
int
del;
if
(
!
lc[t]
||!
rc[t]){
del
=
t;
//
T=(T->lc?T->lc:T->rc);
t
=
lc[t]
+
rc[t];
}
else
{
//
t有两个儿子
del
=
deletion(rc[t],v
-
1
);
//
v==key[t],记录t的后继并复制到t,删除后继
key[t]
=
key[del];
//
若有卫星数据也需复制
}
return
del;
}
else
return
deletion(v
<
key[t]
?
lc[t]:rc[t],v);
}
int
pred(
int
t,
int
v){
if
(
!
t)
return
0
;
if
(v
<=
key[t])
return
pred(rc[t],v);
else
{
int
p
=
pred(rc[t],v);
return
(p
?
p:t);
}
}
int
succ(
int
t,
int
v){
if
(
!
t)
return
0
;
if
(v
>=
key[t])
return
succ(rc[t],v);
else
{
int
s
=
succ(lc[t],v);
return
(s
?
s:t);
}
}
int
select(
int
t,
int
k){
if
(
!
t
||
k
>
sz[t])
return
0
;
int
r
=
(lc[t]
?
sz[lc[t]]:
0
)
+
1
;
if
(k
==
r)
return
t;
if
(k
<
r)
return
select(lc[t],k);
else
return
select(rc[t],k
-
r);
}
int
rank(
int
t,
int
v){
if
(
!
t)
return
0
;
if
(v
==
key[t])
return
(lc[t]
?
sz[lc[t]]:
0
)
+
1
;
if
(v
<
key[t])
return
rank(lc[t],v);
else
{
int
r
=
rank(rc[t],v);
return
r
?
r
+
(lc[t]
?
sz[lc[t]]:
0
)
+
1
:
0
;
}
}
class
CP{
public
:
int
operator
()(Query a,Query b){
if
(a.x
==
b.x)
return
a.y
<
b.y;
return
a.x
<
b.x;
}
};
int
main(){
int
i,j;
while
(scanf(
"
%d%d
"
,
&
n,
&
m)
!=
EOF){
for
(i
=
1
;i
<=
n;i
++
)
scanf(
"
%d
"
,
&
a[i]);
for
(i
=
1
;i
<=
m;i
++
){
scanf(
"
%d%d%d
"
,
&
query[i].x,
&
query[i].y,
&
query[i].k);
if
(query[i].x
>
query[i].y){
int
temp
=
query[i].x;
query[i].x
=
query[i].y;
query[i].y
=
temp;
}
query[i].tag
=
i;
}
sort(query
+
1
,query
+
m
+
1
,CP());
root
=
cnt
=
0
;
for
(j
=
query[
1
].x;j
<=
query[
1
].y;j
++
)
insert(root,a[j]);
ans[query[
1
].tag]
=
key[select(root,query[
1
].k)];
for
(i
=
2
;i
<=
m;i
++
){
if
(query[i
-
1
].y
<
query[i].x
||
query[i
-
1
].x
<
query[i].x
&&
query[i].y
<
query[i
-
1
].y){
root
=
cnt
=
0
;
//
for(j=query[i-1].x;j<=query[i-1].y;j++)
//
deletion(root,a[j]);
for
(j
=
query[i].x;j
<=
query[i].y;j
++
)
insert(root,a[j]);
}
else
{
for
(j
=
query[i
-
1
].x;j
<=
query[i].x
-
1
;j
++
)
deletion(root,a[j]);
for
(j
=
query[i
-
1
].y
+
1
;j
<=
query[i].y;j
++
)
insert(root,a[j]);
}
ans[query[i].tag]
=
key[select(root,query[i].k)];
}
for
(i
=
1
;i
<=
m;i
++
)
printf(
"
%d\n
"
,ans[i]);
}
return
0
;
}