C08【模板】可持久化线段树(主席树)
视频链接:C08 可持久化线段树(主席树)_哔哩哔哩_bilibili
// 主席树 O(nlognlogn) #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define N 200005 #define lc(x) tr[x].l #define rc(x) tr[x].r struct node{ int l,r,s; //s:节点值域中有多少个数 }tr[N*20]; int root[N],idx; int n,m,a[N],b[N]; void insert(int x,int &y,int l,int r,int pos){ y=++idx; //开点 tr[y]=tr[x]; tr[y].s++; if(l==r) return; int m=l+r>>1; if(pos<=m) insert(lc(x),lc(y),l,m,pos); else insert(rc(x),rc(y),m+1,r,pos); } int query(int x,int y,int l,int r,int k){ if(l==r) return l; int m=l+r>>1; int s=tr[lc(y)].s-tr[lc(x)].s; if(k<=s) return query(lc(x),lc(y),l,m,k); else return query(rc(x),rc(y),m+1,r,k-s); } int main(){ scanf("%d%d",&n,&m); for(int i=1; i<=n; i++){ scanf("%d",&a[i]); b[i]=a[i]; } sort(b+1,b+n+1); int bn=unique(b+1,b+n+1)-b-1; //去重后的个数 for(int i=1; i<=n; i++){ int id=lower_bound(b+1,b+bn+1,a[i])-b;//下标 insert(root[i-1],root[i],1,bn,id); } while(m--){ int l,r,k; scanf("%d%d%d",&l,&r,&k); int id=query(root[l-1],root[r],1,bn,k); printf("%d\n",b[id]); } }
#include <iostream> #include <algorithm> #include <vector> using namespace std; #define N 200005 #define lc(x) tr[x].l #define rc(x) tr[x].r struct node{ int l,r,s; //s:节点值域中有多少个数 }tr[N*20]; int root[N],idx; int n,m,a[N]; vector<int> b; void build(int &x,int l,int r){ x=++idx; if(l==r) return; int m=l+r>>1; build(lc(x),l,m); build(rc(x),m+1,r); } void insert(int x,int &y,int l,int r,int k){ y=++idx; tr[y]=tr[x]; tr[y].s++; if(l==r) return; int m=l+r>>1; if(k<=m) insert(lc(x),lc(y),l,m,k); else insert(rc(x),rc(y),m+1,r,k); } int query(int x,int y,int l,int r,int k){ if(l==r) return l; int m=l+r>>1; int s=tr[lc(y)].s-tr[lc(x)].s; if(k<=s) return query(lc(x),lc(y),l,m,k); else return query(rc(x),rc(y),m+1,r,k-s); } int main(){ scanf("%d%d",&n,&m); for(int i=1; i<=n; i++){ scanf("%d",&a[i]); b.push_back(a[i]); } sort(b.begin(),b.end()); b.erase(unique(b.begin(),b.end()),b.end()); int bn=b.size(); build(root[0],1,bn); for(int i=1; i<=n; i++){ int id=lower_bound(b.begin(),b.end(),a[i])-b.begin()+1; insert(root[i-1],root[i],1,bn,id); } while(m--){ int l,r,k; scanf("%d%d%d",&l,&r,&k); int id=query(root[l-1],root[r],1,bn,k)-1; printf("%d\n",b[id]); } return 0; }
P2617 Dynamic Rankings - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P2633 Count on a tree - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P3567 [POI2014] KUR-Couriers - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P2839 [国家集训队] middle - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P3293 [SCOI2016] 美味 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P3168 [CQOI2015] 任务查询系统 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P4559 [JSOI2018] 列队 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P3302 [SDOI2013] 森林 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P4197 Peaks - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P4899 [IOI2018] werewolf 狼人 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P4587 [FJOI2016] 神秘数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P4602 [CTSC2018] 混合果汁 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P3168 [CQOI2015] 任务查询系统 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
Destiny - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)