主席树(一种可持久化线段树)
Posted cmyg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了主席树(一种可持久化线段树)相关的知识,希望对你有一定的参考价值。
study from:
静态主席树:https://blog.csdn.net/a1351937368/article/details/78884526
动态主席树:https://blog.csdn.net/WilliamSun0122/article/details/77885781
静态:
https://www.luogu.org/problemnew/show/P3834
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #include <map> 9 #include <list> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <bitset> 14 #include <ext/rope> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 #define ll long long 19 #define minv 1e-6 20 #define inf 1e9 21 #define pi 3.1415926536 22 #define nl 2.7182818284 23 const ll mod=1e9+7;//998244353 24 const int maxn=2e5+10; 25 26 struct rec 27 { 28 int a,b; 29 }f[maxn]; 30 31 struct node 32 { 33 int l,r,sum,number; 34 }tr[maxn*20]; 35 36 int a[maxn],_index=0,value,tnum=0,result; 37 int be[maxn],v[maxn]; 38 39 int cmp(rec a,rec b) 40 { 41 return a.a<b.a; 42 } 43 44 void ini_build(int l,int r) 45 { 46 tr[_index].sum=0; 47 if (l==r) 48 { 49 tr[_index].l=0; 50 tr[_index].r=0; 51 tr[_index].number=++tnum; 52 } 53 else 54 { 55 int m=(l+r)>>1,cur=_index; 56 tr[cur].l=++_index; 57 ini_build(l,m); 58 59 tr[cur].r=++_index; 60 ini_build(m+1,r); 61 } 62 } 63 64 void build(int l,int r,int pos) 65 { 66 if (l==r) 67 { 68 tr[_index].l=0; 69 tr[_index].r=0; 70 tr[_index].sum=tr[pos].sum+1; ///not 1 71 tr[_index].number=tr[pos].number; 72 } 73 else 74 { 75 int m=(l+r)>>1,cur=_index; 76 tr[cur].sum=tr[pos].sum+1; 77 if (value<=m) 78 { 79 tr[cur].l=++_index; 80 tr[cur].r=tr[pos].r; 81 build(l,m,tr[pos].l); 82 } 83 else 84 { 85 tr[cur].l=tr[pos].l; 86 tr[cur].r=++_index; 87 build(m+1,r,tr[pos].r); 88 } 89 tr[cur].sum=tr[tr[cur].l].sum+tr[tr[cur].r].sum; 90 } 91 } 92 93 void query(int _indexl,int _indexr,int z) 94 { 95 if (tr[_indexl].l==0) 96 { 97 result=tr[_indexl].number; 98 return; 99 } 100 if (tr[tr[_indexr].l].sum-tr[tr[_indexl].l].sum>=z) 101 query(tr[_indexl].l,tr[_indexr].l,z); 102 else 103 query(tr[_indexl].r,tr[_indexr].r,z-tr[tr[_indexr].l].sum+tr[tr[_indexl].l].sum); 104 } 105 106 int main() 107 { 108 int n,m,i,num,x,y,z; 109 scanf("%d%d",&n,&m); 110 for (i=1;i<=n;i++) 111 { 112 scanf("%d",&f[i].a); 113 f[i].b=i; 114 } 115 sort(f+1,f+n+1,cmp); 116 num=0; 117 f[0].a=2e9; 118 for (i=1;i<=n;i++) 119 { 120 if (f[i].a!=f[i-1].a) 121 { 122 num++; 123 v[num]=f[i].a; 124 } 125 a[f[i].b]=num; 126 } 127 be[0]=++_index; 128 ini_build(1,num); 129 for (i=1;i<=n;i++) 130 { 131 be[i]=++_index; 132 value=a[i]; 133 build(1,num,be[i-1]); 134 } 135 136 while (m--) 137 { 138 scanf("%d%d%d",&x,&y,&z); 139 query(be[x-1],be[y],z); 140 printf("%d ",v[result],m); 141 } 142 return 0; 143 } 144 /* 145 5 100 146 1 5 1 5 5 147 1 5 2 148 1 5 3 149 */
以上是关于主席树(一种可持久化线段树)的主要内容,如果未能解决你的问题,请参考以下文章