标签:区间 put 定义 前缀 color fail sort contain algo
7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3
5 6 3
可持久化线段树,又叫主席树。作为模板题我就多说说吧。
可持久化的意思就是可以随时查询线段树维护过程中任何状态。主席树是权值线段树,就是每个值代表一个点,在定义域上建立线段树,[1,1],[1,2],[1,3]...[1,n]这n颗分别维护区间中的信息。这题我们就让主席树变成前缀线段树,然后查询的话就是把第R颗与第L-1颗的差做出来去查询即可
主席树还是动态开点的线段树。(具体看代码)
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cstdio> 5 #include<algorithm> 6 using namespace std; 7 int rt[100005],a[100005],c[100005],s[100005]; 8 struct node{ 9 int l,r,sz,lc,rc; 10 } tr[2000005]; 11 int cnt,tot; 12 inline void update(int x,int y,int p){ 13 tr[x]=tr[y]; 14 tr[x].sz++; 15 int l=tr[x].l,r=tr[x].r; 16 if(l==r) return; 17 int mid=(l+r)>>1; 18 if(p<=mid){ 19 tr[x].lc=++cnt; 20 update(tr[x].lc,tr[y].lc,p); 21 } 22 else{ 23 tr[x].rc=++cnt; 24 update(tr[x].rc,tr[y].rc,p); 25 } 26 } 27 inline void build(int rt,int l,int r) 28 { 29 tr[rt].l=l,tr[rt].r=r; 30 if(l==r) return; 31 int mid=(l+r)>>1; 32 tr[rt].lc=++cnt; build(tr[rt].lc,l,mid); 33 tr[rt].rc=++cnt; build(tr[rt].rc,mid+1,r); 34 } 35 inline int query(int x,int y,int p) 36 { 37 int l=tr[x].l,r=tr[x].r; 38 if(l==r) return l; 39 if(p<=tr[tr[x].lc].sz-tr[tr[y].lc].sz){ 40 return query(tr[x].lc,tr[y].lc,p); 41 } 42 else{ 43 return query(tr[x].rc,tr[y].rc,p-(tr[tr[x].lc].sz-tr[tr[y].lc].sz)); 44 } 45 } 46 int main(){ 47 int n,q,L,R,k; 48 scanf("%d%d",&n,&q); 49 for(int i=1;i<=n;i++){ 50 scanf("%d",&a[i]); 51 c[i]=a[i]; 52 } 53 sort(c+1,c+n+1); 54 for(int i=1;i<=n;i++){ 55 if(c[i]!=c[i-1]) s[++tot]=c[i]; 56 } 57 rt[0]=++cnt; 58 build(rt[0],1,tot); 59 for(int i=1;i<=n;i++){ 60 int p=lower_bound(s+1,s+tot+1,a[i])-s; 61 rt[i]=++cnt; 62 update(rt[i],rt[i-1],p); 63 } 64 while(q--){ 65 scanf("%d%d%d",&L,&R,&k); 66 printf("%d\n",s[query(rt[R],rt[L-1],k)]); 67 } 68 return 0; 69 }
标签:区间 put 定义 前缀 color fail sort contain algo
原文地址:http://www.cnblogs.com/Dndlns/p/7892534.html