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 }
View Code

 

posted @ 2019-09-03 19:49  zjxxcn  阅读(203)  评论(0编辑  收藏  举报