[loj6088]可持久化最长不降子序列
Posted pywbktda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[loj6088]可持久化最长不降子序列相关的知识,希望对你有一定的参考价值。
考虑二分求LIS的过程,就是维护一个序列,其中第i个数表示长度为i的最小结尾,而插入操作就是查找第一个大于x的位置并替换掉
用线段树维护,二分的过程也可以用线段树来完成,对线段树可持久化即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 500005 4 #define mid (l+r>>1) 5 int B,V,n,p,x,y,r[N],ans[N],f[N*30],ls[N*30],rs[N*30]; 6 int copy(int k) 7 f[++V]=f[k]; 8 ls[V]=ls[k]; 9 rs[V]=rs[k]; 10 return V; 11 12 void build(int &k,int l,int r) 13 f[k=++V]=0x3f3f3f3f; 14 if (l==r) 15 if (!l)f[k]=-0x3f3f3f3f; 16 return; 17 18 build(ls[k],l,mid); 19 build(rs[k],mid+1,r); 20 f[k]=max(f[ls[k]],f[rs[k]]); 21 22 void update(int &k,int l,int r,int x,int y) 23 k=copy(k); 24 if (l==r) 25 f[k]=y; 26 return; 27 28 if (x<=mid)update(ls[k],l,mid,x,y); 29 else update(rs[k],mid+1,r,x,y); 30 f[k]=max(f[ls[k]],f[rs[k]]); 31 32 int query(int k,int l,int r,int x) 33 if (l==r)return l; 34 if (f[ls[k]]>x)return query(ls[k],l,mid,x); 35 return query(rs[k],mid+1,r,x); 36 37 int main() 38 scanf("%d",&n); 39 build(r[0],0,n); 40 for(int i=1;i<=n;i++) 41 scanf("%d%d",&p,&x); 42 if (p)printf("%d\n",ans[B=x]); 43 else 44 B++; 45 y=query(r[B]=r[B-1],0,n,x); 46 if (y)update(r[B],0,n,y,x); 47 printf("%d\n",ans[B]=max(ans[B-1],y)); 48 49 50
以上是关于[loj6088]可持久化最长不降子序列的主要内容,如果未能解决你的问题,请参考以下文章
luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
D1. Kirk and a Binary String (easy version)