主席树(一种可持久化线段树)

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 */

 

以上是关于主席树(一种可持久化线段树)的主要内容,如果未能解决你的问题,请参考以下文章

Yangk's 静态主席树-模板

可持久化线段树(主席树)

主席树乱讲

主席树小结

可持续化线段树(主席树)

p3834 可持久化线段树模板(主席树)