zoukankan      html  css  js  c++  java
  • 题解CF490F Treeland Tour

    题目:CF490F Treeland Tour

    树上的最长上升子序列问题,先给出O(n^2logn)的算法。

    虽然有更优的动态开点权值线段树的做法,但是我不太会写。以后慢慢补上吧。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define it register int
     4 #define il inline
     5 using namespace std;
     6 const int N=2000005;
     7 int n,a[N],h[N],nxt[N],adj[N],w[N],s[N],top,t,ans,fa[N]; 
     8 il int Max(it p,it q){
     9     return p>q?p:q;
    10 }
    11 il void add(it u,it v){
    12     nxt[++t]=h[u],h[u]=t,adj[t]=v;
    13     nxt[++t]=h[v],h[v]=t,adj[t]=u;
    14 }
    15 void fr(int &num){
    16     num=0;char c=getchar();int p=1;
    17     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
    18     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    19     num*=p;
    20 }
    21 il void dfs(it x,it fa){
    22     it now=lower_bound(s+1,s+1+n,w[x])-s; 
    23     ans=Max(ans,now);it tx=s[now];s[now]=w[x];
    24     for(it i=h[x];i;i=nxt[i])
    25         if(adj[i]!=fa)
    26             dfs(adj[i],x);
    27     s[now]=tx;
    28 }
    29 int main(){
    30     fr(n);
    31     for(it i=1;i<=n;++i) fr(w[i]),s[i]=0x7fffffff;
    32     for(it i=1,u,v;i<n;++i) fr(u),fr(v),add(u,v);
    33     for(it i=1;i<=n;++i) dfs(i,-1);
    34     printf("%d",ans); 
    35     return 0;
    36 }
    View Code

    我们每次遍历以当前节点为根的树的最长上升子序列。每次dfs之前求一下w[x]可以放的位置,dfs之后再还原原数。这样我们可以保证递归到叶子节点时我们求出了子树的最优解。

  • 相关阅读:
    mysql-03
    mysql-02
    mysql-01
    RESTFUL设计风格
    mysql水平拆分和垂直拆分
    redis连环夺命问
    Python 的十大重要特性
    吊打--redis
    python2和3 的区别
    tornado第一段代码
  • 原文地址:https://www.cnblogs.com/Kylin-xy/p/11638655.html
Copyright © 2011-2022 走看看