Persistent Line Segment Tree

Linknode

可持久化:能夠保存歷史版本算法

權值線段樹:每個葉子節點a[i]:表示 i 出現的次數ide

學習資料:前置技能:可持久化含義,權值線段樹,可參考Menci博客學習

                  寫法可參考bilibili中qsc算法講堂spa

離散化:vector排序後erase,low_bound查找便可.net

模板blog

#include<stdio.h>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 1e5+7;

int n,q,root[maxn],a[maxn],l,r,k,cnt;
vector<int>v;

struct node{
    int l,r,sum;
}t[maxn*40];

int get_id(int x){
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}

void update(int l,int r,int &x,int y,int k){
    t[++cnt]=t[y],t[cnt].sum++,x=cnt;
    if(l==r) return;
    int mid=(l+r)/2;
    if(k<=mid) update(l,mid,t[x].l,t[y].l,k);
    else update(mid+1,r,t[x].r,t[y].r,k);

}

int query(int l,int r,int x,int y,int k){
    if(l==r) return l;
    int mid=(l+r)/2;
    int sum=t[t[y].l].sum-t[t[x].l].sum;
    if(sum>=k) query(l,mid,t[x].l,t[y].l,k);
    else query(mid+1,r,t[x].r,t[y].r,k-sum);

}

int main(){
    while(scanf("%d%d",&n,&q)!=EOF){
        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++){
            update(1,n,root[i],root[i-1],get_id(a[i]));
        }
        while(q--){
            scanf("%d%d%d",&l,&r,&k);
            printf("%d\n", v[query(1,n,root[l-1],root[r],k)-1]);
        }
    }
}

kuangbin專題排序

Aci

分析get

主席樹板子題


B     SPOJ COT

分析

根據dfs序建主席樹,lca求最近公共祖先結點後,正常的按照主席樹查詢第k大便可


動態求區間第k大

分析

 待補


HDU4348

分析

對每一個t創建主席樹,像線段樹那樣加lazy,主席樹求和傳遞lazy便可

相關文章
相關標籤/搜索