最后两个数据点WA了,请大佬帮忙看一下
#include <bits/stdc++.h>
using namespace std;
#define N 200000
long long int a[N], cpy[N];
int lsh[N];
int cnt; /*节点编号*/
int root[N]; /*记录第i个“线段树”根节点编号*/
int ma; /*数据离散化之后的最大值*/
struct node{
int ls, rs, val;
/*该节点左、右儿子节点编号;权值*/
}tree[32 * N];
void buildtree(int i, int l, int r)
/*当前第i个节点;线段左端点;线段右端点*/
{
cnt++;
if (l == r)
return;
tree[i].ls = 2 * i;tree[i].rs = 2 * i + 1;
int mid = (l + r) / 2;
buildtree(2 * i, l, mid);
buildtree(2 * i + 1, mid + 1, r);
}
void change(int l, int r, int now, int past, int k);
void add(int i, int k)
/*当前“线段树”的编号;将插入的数*/
{
root[i] = ++cnt;
/*cnt现在是新“线段树”的根节点节点编号*/
tree[cnt].val = tree[root[i - 1]].val + 1;
/*新建节点完毕,开始向下延伸*/
change(1, ma, cnt, root[i - 1], k);
}
void change(int l, int r, int now, int past, int k)
/*当前区间[l r];新“线段树”的当前节点编号now;
上一棵“线段树”的当前节点编号past;将插入的数*/
{
/*如果已经遍历到叶子结点*/
if (!tree[past].ls && !tree[past].rs)
return;
int mid = (l + r) / 2;
/*如果要插入的数即将影响该节点的右儿子区间*/
if (k > mid)
{
/*连上上一棵树的左儿子作为新树的左儿子*/
tree[now].ls = tree[past].ls;
/*右儿子需要开新点*/
tree[now].rs = ++cnt;
/*更新右儿子的权值*/
tree[cnt].val = tree[tree[past].rs].val + 1;
change(mid + 1, r, cnt, tree[past].rs, k);
}
else
{
/*左边一样的道理*/
tree[now].rs = tree[past].rs;
tree[now].ls = ++cnt;
tree[cnt].val = tree[tree[past].ls].val + 1;
change(l, mid, cnt, tree[past].ls, k);
}
}
int kth(int a, int b, int l, int r, int k)
/*区间首尾对应的“线段树”根节点a, b;当前区间[l r];查询第k小的数*/
{
if (l == r)
return l;
int lm = tree[tree[b].ls].val - tree[tree[a].ls].val;
/*lm是区间[a b]的权值二叉树根节点左儿子的值*/
int mid = (l + r) / 2;
if (k <= lm)
return kth(tree[a].ls, tree[b].ls, l, mid, k);
return kth(tree[a].rs, tree[b].rs, mid + 1, r, k - lm);
}
int main()
{
int n, m, i;
scanf("%d%d", &n, &m);
for (i = 1;i <= n;i++)
{
scanf("%lld", &a[i]);
cpy[i] = a[i];
}
sort(a + 1, a + 1 + n);
ma = unique(a + 1, a + 1 + n) - (a + 1);
for (i = 1;i <= n;i++)
lsh[i] = lower_bound(a + 1, a + 1 + ma, cpy[i]) - a;
/*建空树*/
buildtree(1, 1, ma);
root[0] = 1;
for (i = 1;i <= n;i++)
add(i, lsh[i]);
while (m--)
{
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
int ans = kth(root[l - 1], root[r], 1, ma, k);
printf("%lld\n", a[ans]);
}
return 0;
}