标签:col ++ pre 线段树 ret for mes print using
树上LIS:树上找一条简单路径的子序列使点权严格单增,最大化长度。
原题数据过小,用线段树合并可以做到$O(n\log n)$。
每个点用一棵线段树维护以每个权值为结尾的LIS最长长度,线段树合并时更新子序列不包含当前点时的最大值,再线段树上区间询问得到包含时的最大值并更新线段树。
1 #include<cstdio> 2 #include<algorithm> 3 #define lson ls[x],L,mid 4 #define rson rs[x],mid+1,R 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 #define For(i,x) for (int i=h[x],k; i; i=nxt[i]) 7 using namespace std; 8 9 const int N=100010; 10 int n,u,v,ans,nd,cnt,tot,lis[N*25],lds[N*25],ls[N*25],rs[N*25]; 11 int h[N],to[N<<1],nxt[N<<1],rt[N],a[N],b[N]; 12 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } 13 14 int merge(int x,int y){ 15 if (!x || !y) return x|y; 16 lis[x]=max(lis[x],lis[y]); lds[x]=max(lds[x],lds[y]); 17 ans=max(ans,max(lis[ls[x]]+lds[rs[y]],lds[rs[x]]+lis[ls[y]])); 18 ls[x]=merge(ls[x],ls[y]); rs[x]=merge(rs[x],rs[y]); return x; 19 } 20 21 void mdf(int &x,int L,int R,int p,int k,int a[]){ 22 if (!x) x=++nd; 23 a[x]=max(a[x],k); int mid=(L+R)>>1; 24 if (L==R) return; 25 if (p<=mid) mdf(lson,p,k,a); else mdf(rson,p,k,a); 26 } 27 28 int que(int x,int L,int R,int l,int r,int a[]){ 29 if (L==l && r==R) return a[x]; 30 int mid=(L+R)>>1; 31 if (r<=mid) return que(lson,l,r,a); 32 else if (l>mid) return que(rson,l,r,a); 33 else return max(que(lson,l,mid,a),que(rson,mid+1,r,a)); 34 } 35 36 void dfs(int x,int fa){ 37 For(i,x) if ((k=to[i])!=fa) dfs(k,x); 38 int s1=0,s2=0,t1,t2; 39 For(i,x) if ((k=to[i])!=fa){ 40 t1=a[x]>1 ? que(rt[k],1,tot,1,a[x]-1,lis) : 0; 41 t2=a[x]<tot ? que(rt[k],1,tot,a[x]+1,tot,lds) : 0; 42 rt[x]=merge(rt[x],rt[k]); ans=max(ans,max(s1+t2+1,s2+t1+1)); 43 s1=max(s1,t1); s2=max(s2,t2); 44 } 45 mdf(rt[x],1,tot,a[x],s1+1,lis); mdf(rt[x],1,tot,a[x],s2+1,lds); 46 } 47 48 int main(){ 49 freopen("490F.in","r",stdin); 50 freopen("490F.out","w",stdout); 51 scanf("%d",&n); 52 rep(i,1,n) scanf("%d",&a[i]),b[i]=a[i]; 53 sort(b+1,b+n+1); tot=unique(b+1,b+n+1)-b-1; 54 rep(i,1,n) a[i]=lower_bound(b+1,b+tot+1,a[i])-b; 55 rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u); 56 dfs(1,0); printf("%d\n",ans); 57 return 0; 58 }
标签:col ++ pre 线段树 ret for mes print using
原文地址:https://www.cnblogs.com/HocRiser/p/10575651.html