社区讨论

10pts,求条,必关

P3834【模板】可持久化线段树 2参与者 5已保存回复 20

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
18 条
当前快照
1 份
快照标识符
@mdnvzs2c
此快照首次捕获于
2025/07/29 09:57
7 个月前
此快照最后确认于
2025/11/04 06:28
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct Tree{
    struct str{
        int l,r,sum;
    };
    vector<str> tree;
    vector<int> root;
    void init(int x){root.push_back(build(1,x));}
    int build(int l,int r)
    {
        tree.push_back({-1,-1,0});
        int id=tree.size()-1;
        if(l==r) return id;
        int mid=(l+r)>>1;
        tree[id].l=build(l,mid);
        tree[id].r=build(mid+1,r);
        return id;
    }
    int update(int pre,int l,int r,int pos)
    {
        tree.push_back(tree[pre]);
        int id=tree.size()-1;
        tree[id].sum++;
        if(l==r) return id;
        int mid=(l+r)>>1;
        if(pos<=mid) tree[id].l=update(tree[pre].l,l,mid,pos);
        else tree[id].r=update(tree[pre].r,mid+1,r,pos);
        return id;
    }
    int ask(int y,int x,int l,int r,int k)
    {
        if(l==r) return l;
        int mid=(l+r)>>1;
        int lcnt=tree[tree[x].l].sum-tree[tree[y].l].sum;
        if(lcnt>=k) return ask(tree[y].l,tree[x].l,l,mid,k);
        else return ask(tree[y].r,tree[x].r,mid+1,r,k-lcnt);
    }
};
int main()
{
    scanf("%d%d",&n,&m);
    vector<int> a(4*n),sa(4*n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        sa[i]=a[i];
    }
    sort(sa.begin(),sa.end());  
    sa.erase(unique(sa.begin(),sa.end()),sa.end());
    int len=sa.size();
    auto rank=[&](int x)
    {
        return lower_bound(sa.begin(),sa.end(),x)-sa.begin()+1;
    };
    Tree pt;
    pt.init(len);
    for(int j=0;j<n;j++)
    {
        int rk=rank(a[j]);
        int nrt=pt.update(pt.root[j],1,len,rk);
        pt.root.push_back(nrt);
    }
    while(m--)
    {
        int l,r,s;
        scanf("%d%d%d",&l,&r,&s);
        int rak=pt.ask(pt.root[l-1],pt.root[r],1,len,s);
        printf("%d\n",sa[rak-1]); 
    }
    return 0;
}

回复

20 条回复,欢迎继续交流。

正在加载回复...