loj 6088 可持久化最长不降子序列
我们对最长不下降子序的单调序列进行维护,用可持久化平衡树来维护。 (ps我写的好像是主席树)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int const N=500000+10; 4 int const M=N*20; 5 int rt[N],sz[M],mx[M],sum,n,ch[M][2]; 6 int find(int x,int l,int r,int v){ 7 if(l==r) return l; 8 int mid=(l+r)/2; 9 if(mx[ch[x][0]]>v) return find(ch[x][0],l,mid,v); 10 else return find(ch[x][1],mid+1,r,v); 11 } 12 void copy(int x,int y){ 13 sz[x]=sz[y];mx[x]=mx[y];ch[x][0]=ch[y][0];ch[x][1]=ch[y][1]; 14 } 15 void insert(int now,int &x,int l,int r,int p,int v){ 16 x=++sum; 17 copy(x,now); 18 if(l==r){ 19 sz[x]=1; mx[x]=v; return ; 20 } 21 int mid=(l+r)/2; 22 if(p<=mid) insert(ch[now][0],ch[x][0],l,mid,p,v); 23 else insert(ch[now][1],ch[x][1],mid+1,r,p,v); 24 mx[x]=max(mx[ch[x][0]],mx[ch[x][1]]); 25 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]; 26 } 27 int main(){ 28 int now=0; 29 rt[0]=sum=1; 30 scanf("%d",&n); 31 for(int i=1;i<=n;i++){ 32 int opt,x; 33 scanf("%d%d",&opt,&x); 34 if(opt==0){ 35 if(sz[rt[now]] && mx[rt[now]]>x){ 36 int t=find(rt[now],1,n,x); 37 insert(rt[now],rt[now+1],1,n,t,x); 38 }else { 39 insert(rt[now],rt[now+1],1,n,sz[rt[now]]+1,x); 40 } 41 now++; 42 }else now=x; 43 printf("%d\n",sz[rt[now]]); 44 } 45 return 0; 46 }