社区讨论

萌新刚学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 条回复,欢迎继续交流。

正在加载回复...