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便可