日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

主席树 - 可持久化线段树

發布時間:2023/12/3 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 主席树 - 可持久化线段树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

模板

P3834 【模板】可持久化線段樹 2(主席樹) 區間求第 \(k\)

模板代碼 #include<bits/stdc++.h> using namespace std; #define Maxn 200005 typedef long long ll; inline int rd() {int x=0;char ch,t=0;while(!isdigit(ch = getchar())) t|=ch=='-';while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();return x=t?-x:x; } /* len: 數組長度 cnt: 數據范圍 */ int len,n,m,used; int root[Maxn],a[Maxn],True_val[Maxn]; struct Li {int val,num; }LI[Maxn]; bool cmp(Li x,Li y) { return x.val<y.val; } struct Tree {int ls,rs,sum; }tree[Maxn<<5]; void pushup(int p) {tree[p].sum=tree[tree[p].ls].sum+tree[tree[p].rs].sum; } void build(int p,int nl,int nr) {if(nl==nr) return;int mid=(nl+nr)>>1;if(mid>=nl) tree[p].ls=++used,build(tree[p].ls,nl,mid);if(mid<nr) tree[p].rs=++used,build(tree[p].rs,mid+1,nr); } void add(int p1,int p2,int nl,int nr,int pos,int k) {if(nl==nr) { tree[p2].sum=tree[p1].sum+k; return; }int mid=(nl+nr)>>1;tree[p2]=tree[p1];if(pos<=mid) tree[p2].ls=++used,add(tree[p1].ls,tree[p2].ls,nl,mid,pos,k);else tree[p2].rs=++used,add(tree[p1].rs,tree[p2].rs,mid+1,nr,pos,k);pushup(p2); } int query(int p1,int p2,int nl,int nr,int rank) {if(nl==nr) return nl;int sumls=tree[tree[p2].ls].sum-tree[tree[p1].ls].sum,mid=(nl+nr)>>1;if(rank<=sumls) return query(tree[p1].ls,tree[p2].ls,nl,mid,rank);else return query(tree[p1].rs,tree[p2].rs,mid+1,nr,rank-sumls); } int main() {//freopen(".in","r",stdin);//freopen(".out","w",stdout);len=rd(),m=rd();for(int i=1;i<=len;i++) LI[i].val=rd(),LI[i].num=i;sort(LI+1,LI+len+1,cmp),LI[0].val=-1;for(int i=1;i<=len;i++){if(LI[i].val!=LI[i-1].val) n++;a[LI[i].num]=n;True_val[n]=LI[i].val;}for(int i=0;i<=len;i++) root[i]=++used;build(root[0],1,n);for(int i=1;i<=len;i++) add(root[i-1],root[i],1,n,a[i],1);for(int i=1,l,r,k;i<=m;i++){l=rd(),r=rd(),k=rd();printf("%d\n",True_val[query(root[l-1],root[r],1,n,k)]);}//fclose(stdin);//fclose(stdout);return 0; }

例題

P3899 [湖南集訓]更為厲害

主要實現內容:給定一棵樹,每次詢問求出 \(u\) 的子樹內,與 \(u\) 距離不超過 \(k\) 的所有節點的點權之和。

可以考慮以 \(dfn\) 序列作為 \(root[]\) ,每一個節點開一棵主席樹。

修改時以每個點的深度為下標,附上點權。

這樣就可以快速查詢一顆子樹(一段區間),并查詢制指定深度的點權之和。

總結

以上是生活随笔為你收集整理的主席树 - 可持久化线段树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。