社区讨论
萌新刚学OI求帮看代码
P3834【模板】可持久化线段树 2参与者 11已保存回复 12
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 12 条
- 当前快照
- 1 份
- 快照标识符
- @mi6ykngw
- 此快照首次捕获于
- 2025/11/20 12:55 4 个月前
- 此快照最后确认于
- 2025/11/20 15:33 4 个月前
CPP
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
constexpr int maxn = 200000 + 10;
constexpr int maxm = maxn;
//Constant Data
int n, m;
int Original_Data[maxn], Index_Unique[maxn], Unique_Size;
class Functional_SegmentTree
{
private:
//int SizeofTree;
int VersionNow = 0;
struct Node
{
int Val = 0;
Node *lson = nullptr, *rson = nullptr;
};
Node **roots;
inline void __build_basetree(Node *now, int l, int r)
{
if (l < r)
{
now->lson = new Node;
now->rson = new Node;
__build_basetree(now->lson, l, (l + r) / 2);
__build_basetree(now->rson, ((l + r) / 2) + 1, r);
}
}
inline void __build_new_ver(Node *PreVer, Node *now, int l, int r, int value)
{
*now = *PreVer;
now->Val++;
if (l < r)
{
if (value <= (l + r) / 2)
{
now->lson = new Node;
__build_new_ver(PreVer->lson, now->lson, l, (l + r) / 2, value);
}
else
{
now->rson = new Node;
__build_new_ver(PreVer->rson, now->rson, (l + r) / 2 + 1, r, value);
}
}
}
inline int __query(Node *a, Node *b, int l, int r, int k)
{
if (!(l < r))
return l;
int p=b->lson->Val-a->lson->Val;
if (p >= k)
return __query(a->lson, b->lson, l, (l + r) / 2, k);
else
return __query(a->rson, b->rson, (l + r) / 2 + 1, r, k - p);
}
public:
Functional_SegmentTree(int n)
{
//SizeofTree = n;
roots = new Node *[n];
roots[0] = new Node;
__build_basetree(roots[0], 1, n);
}
inline void Build_New_Version(int l, int r, int Value)
{
roots[VersionNow + 1] = new Node;
__build_new_ver(roots[VersionNow], roots[VersionNow + 1], l, r, Value);
VersionNow++; //Update
}
inline int Query(int l, int r, int k)
{
return __query(roots[l - 1], roots[r], 1, Unique_Size, k);
}
};
int main()
{
scanf("%d%d", &n, &m);
for (/*register*/ int i = 1; i <= n; i++) //Because of the SegmentTree,so we must start from 1;
scanf("%d", &Original_Data[i]),
Index_Unique[i] = Original_Data[i]; //Copy
sort(Index_Unique + 1, Index_Unique + n + 1);
Unique_Size = unique(Index_Unique + 1, Index_Unique + n + 1) - Index_Unique - 1;
Functional_SegmentTree AC_Tools(Unique_Size);
for (int i = 1; i <= n; i++)
AC_Tools.Build_New_Version(1, Unique_Size, lower_bound(Index_Unique + 1, Index_Unique + Unique_Size + 1, Original_Data[i]) - Index_Unique);
for (int i = 1; i <= m; i++)
{
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
printf("%d\n", Index_Unique[AC_Tools.Query(l, r, k)]);
}
}
回复
共 12 条回复,欢迎继续交流。
正在加载回复...