区间第k大查询
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1000 + 10;
struct Node
{
int l, r, sum;
} hjt[maxn * 40];
int n, m, a[maxn];
int cnt, root[maxn];
vector<int> v;
bool cmp(int a, int b)
{
return a > b;
}
int GetID(int x)
{
return lower_bound(v.begin(), v.end(), x, greater<int>()) - v.begin() + 1;
}
void insert(int L, int R, int pre, int &node, int p) // pre 为上一颗线段树的根节点 ,node为当前线段树的根节点
{
hjt[++cnt] = hjt[pre];
node = cnt;
hjt[node].sum++;
if (L == R)
return;
int mid = (L + R) >> 1;
if (p <= mid)
insert(L, mid, hjt[pre].l, hjt[node].l, p);
else
insert(mid + 1, R, hjt[pre].r, hjt[node].r, p);
}
int query(int start, int end, int L, int R, int k)
{
if (start == end)
return end;
int mid = (start + end) >> 1;
int temp = hjt[hjt[R].l].sum - hjt[hjt[L].l].sum;
if (k <= temp)
return query(start, mid, hjt[L].l, hjt[R].l, k);
else
return query(mid + 1, end, hjt[L].r, hjt[R].r, k - temp);
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
#endif
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
v.push_back(a[i]);
}
sort(v.begin(), v.end(), cmp);
v.erase(unique(v.begin(), v.end()), v.end());
// cout << "去重后数组元素" << endl;
// for (int i = 0; i < v.size(); i++)
// {
// cout << v[i] << " ";
// }
// cout << endl;
for (int i = 1; i <= n; i++)
{
// cout << a[i] << " 在去重数组中为第 " << GetID(a[i]) << " 大" << endl;
insert(1, n, root[i - 1], root[i], GetID(a[i]));
}
cin >> m;
int x, y, k;
while (m--)
{
cin >> x >> y >> k;
cout << v[query(1, n, root[x - 1], root[y], k) - 1] << endl;
}
return 0;
}
区间第k小查询
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 2e5 + 10;
vector<int> v;
int n, m, a[maxn]; // a为原数组
int cnt, root[maxn]; // root 根节点数组
struct Node
{
int l, r, sum;
} hjt[maxn * 40];
int GetId(int x)
{
return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
}
void insert(int L, int R, int pre, int &node, int p) // pre 为上一颗线段树的根节点 ,node为当前线段树的根节点
{
hjt[++cnt] = hjt[pre];
node = cnt;
hjt[node].sum++;
if (L == R)
return;
int mid = (L + R) >> 1;
if (p <= mid)
insert(L, mid, hjt[pre].l, hjt[node].l, p);
else
insert(mid + 1, R, hjt[pre].r, hjt[node].r, p);
}
int query(int start, int end, int L, int R, int k)
{
if (start == end)
return end;
int mid = (start + end) >> 1;
int temp = hjt[hjt[R].l].sum - hjt[hjt[L].l].sum;
if (k <= temp)
return query(start, mid, hjt[L].l, hjt[R].l, k);
else
return query(mid + 1, end, hjt[L].r, hjt[R].r, k - temp);
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
#endif
freopen("out.txt", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
v.push_back(a[i]);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 1; i <= n; i++)
{
insert(1, n, root[i - 1], root[i], GetId(a[i]));
}
int x, y, k;
while (m--)
{
scanf("%d %d %d", &x, &y, &k);
printf("%d\n", v[query(1, n, root[x - 1], root[y], k)-1]);
}
cout << cnt << endl;
return 0;
}