zoukankan      html  css  js  c++  java
  • hdu 4718 The LCIS on the Tree

    The LCIS on the Tree

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
    Total Submission(s): 528    Accepted Submission(s): 165


    Problem Description
    For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i <= j <= N and Si < Si+1 < Si+2 < ... < Sj-1 < Sj , then the sequence Si, Si+1, ... , Sj is a CIS(Continuous Increasing Subsequence). The longest CIS of a sequence is called the LCIS (Longest Continuous Increasing Subsequence).
    Now we consider a tree rooted at node 1. Nodes have values. We have Q queries, each with two nodes u and v. You have to find the shortest path from u to v. And write down each nodes' value on the path, from u to v, inclusive. Then you will get a sequence, and please show us the length of its LCIS.
     
    Input
    The first line has a number T (T <= 10) , indicating the number of test cases.
    For each test case, the first line is a number N (N <= 105), the number of nodes in the tree.
    The second line comes with N numbers v1, v2, v3 ... , vN, describing the value of node 1 to node N. (1 <= vi <= 109)
    The third line comes with N - 1 numbers p2, p3, p4 ... , pN, describing the father nodes of node 2 to node N. Node 1 is the root and will have no father.
    Then comes a number Q, it is the number of queries. (Q <= 105)
    For next Q lines, each with two numbers u and v. As described above.
     
    Output
    For test case X, output "Case #X:" at the first line.
    Then output Q lines, each with an answer to the query.
    There should be a blank line *BETWEEN* each test case.
     
    Sample Input
    1
    5
    1 2 3 4 5
    1 1 3 3
    3
    1 5
    4 5
    2 5
     
    Sample Output
    Case #1:
    3
    2
    3
     
    Source
     
    题意:给你一棵树,每个点都有一个权值,每个询问 u v 
    求 u 到 v 路径上节点权值序列的最长上升子序列
     
    思路:数链剖分,线段树维护左到右的最长上升子序列,和右到左的最长上升子序列,
    合并注意点就好了。。
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<set>
    #include<stack>
    #include<map>
    #include<ctime>
    #include<bitset>
    #define LL long long
    #define ll long long
    #define INF 0x3f3f3f3f
    #define maxn 100010
    #define eps 1e-6
    #define mod 1000000007
    using namespace std;
    
    struct node
    {
        int ls,rs,lmax,rmax,max1,max2;
        int len,Lmax,Rmax;
        void init()
        {
            ls=rs=lmax=rmax=0;
            max1=max2=Lmax=Rmax=0;
            len=0;
        }
    }tree[maxn*3];
    int head[maxn],to[maxn*2],next1[maxn*2] ;
    int tot,val[maxn],fa[maxn],top[maxn];
    int dep[maxn],son[maxn],w[maxn];
    int sz,ql,qr,n;
    node v;
    
    node Unit(node &a,node &b)
    {
        node ans;
        ans.len=a.len+b.len ;
        ans.ls=a.ls ;
        ans.rs=b.rs ;
        ans.max1=max(a.max1,b.max1) ;
        ans.max2=max(a.max2,b.max2) ;
    
        if(a.rs < b.ls )
        {
            if(a.lmax==a.len)
               ans.lmax = a.lmax+b.lmax ;
            else ans.lmax=a.lmax;
            ans.max1=max(ans.max1,a.rmax+b.lmax) ;
            if(b.rmax==b.len)
               ans.rmax = a.rmax+b.rmax ;
            else ans.rmax=b.rmax;
        }
        else {
             ans.lmax = a.lmax ;
             ans.rmax = b.rmax ;
        }
    
        if(b.ls < a.rs )
        {
            if(a.Lmax==a.len)
              ans.Lmax = a.Lmax+b.Lmax ;
            else ans.Lmax=a.Lmax;
            ans.max2=max(ans.max2,a.Rmax+b.Lmax) ;
            if(b.Rmax == b.len)
              ans.Rmax = a.Rmax+b.Rmax ;
            else ans.Rmax=b.Rmax;
        }
        else {
             ans.Lmax = a.Lmax ;
             ans.Rmax = b.Rmax ;
        }
        return ans;
    }
    void Unit(int u,int v)
    {
        to[tot]=v;next1[tot]=head[u];
        head[u]=tot++;
    }
    void dfs(int u,int f)
    {
        son[u]=0;w[u]=1;
        int i,v;
        for( i = head[u] ; i != -1; i = next1[i])
        {
            v = to[i] ;
            if(v==f) continue ;
            fa[v]=u;
            dep[v]=dep[u]+1;
            dfs(v,u) ;
            if(w[v]>w[son[u]])
                son[u]=v;
            w[u] += w[v] ;
        }
    }
    void build(int u,int f,int t)
    {
        w[u]=++sz ;
        top[u]=t;
        if(son[u])build(son[u],u,t) ;
        for( int i = head[u] ; i != -1 ; i = next1[i])
            if(son[u] != to[i]&&f != to[i])
             build(to[i],u,to[i]) ;
    }
    void init(int L,int R,int o)
    {
        if(L==R)
        {
            tree[o].ls=tree[o].rs=son[L] ;
            tree[o].len=tree[o].max1=tree[o].max2=1;
            tree[o].lmax=tree[o].Lmax=1;
            tree[o].Rmax=tree[o].rmax = 1;
            return ;
        }
        int mid=(L+R)>>1;
        init(L,mid,o<<1) ;
        init(mid+1,R,o<<1|1) ;
        tree[o]=Unit(tree[o<<1],tree[o<<1|1]) ;
    }
    
    void find(int L,int R,int o)
    {
        if(ql<=L&&qr>=R)
        {
            if(v.max1==0)v=tree[o] ;
            else v = Unit(v,tree[o]) ;
            return ;
        }
        int mid=(L+R)>>1 ;
        if(ql<=mid) find(L,mid,o<<1) ;
        if(qr>mid) find(mid+1,R,o<<1|1);
    }
    
    int solve(int u,int vv)
    {
        int f1,f2;
        node v1,v2;
        v1.init();
        v2.init();
        f1=top[u];
        f2=top[vv];
        while(f1 != f2)
        {
            if(dep[f1]>dep[f2])
            {
                ql=w[f1];
                qr=w[u] ;
                v.init();
                find(1,sz,1) ;
                if(v1.max1==0)
                    v1=v;
                else v1=Unit(v,v1) ;
                u=fa[f1];
                f1=top[u];
            }
            else{
                ql=w[f2];
                qr=w[vv] ;
                v.init();
                find(1,sz,1) ;
                if(v2.max1==0)
                    v2=v;
                else v2=Unit(v,v2) ;
                vv=fa[f2] ;
                f2=top[vv] ;
            }
        }
        int ans=0;
        if(u==vv&&0){
            ans=max(v1.max2,v2.max1);
            if(v1.ls < v2.ls)
            {
                ans=max(ans,v1.Lmax+v2.lmax) ;
            }
            return ans;
        }
        else
        {
            if(dep[u]>dep[vv])
            {
                ql=w[vv];
                qr=w[u];
                v.init();
                find(1,sz,1) ;
                if(v1.max1==0)v1=v;
                else v1=Unit(v,v1) ;
            }
            else
            {
                ql=w[u];
                qr=w[vv];
                v.init();
                find(1,sz,1) ;
                if(v2.max1==0)v2=v;
                else v2=Unit(v,v2) ;
            }
        }
        ans=max(v1.max2,v2.max1);
        if(v1.ls < v2.ls)
        {
            ans=max(ans,v1.Lmax+v2.lmax) ;
        }
        return ans;
    }
    
    int main()
    {
        int i,m,k,case1=0;
        int j ,T,x,y ;
       // freopen("in.txt","r",stdin);
       // freopen("yy.txt","w",stdout);
       bool hehe=false;
        cin >> T ;
        while(T--)
        {
            if(hehe)puts("") ;
            hehe=true;
            scanf("%d",&n) ;
            for( i =1 ; i <= n ;i++)
                scanf("%d",&val[i]) ;
            tot=0;
            memset(head,-1,sizeof(head)) ;
            for( i = 2 ; i <= n ;i++)
            {
                scanf("%d",&k) ;
                Unit(k,i) ;
                Unit(i,k) ;
            }
            dep[1]=0;
            fa[1]=1;
            sz=0;
            dfs(1,-1) ;
            build(1,-1,1) ;
            for( i = 1 ; i <= n ;i++)
            {
                son[w[i]]=val[i] ;
            }
            init(1,sz,1) ;
            scanf("%d",&m) ;
            printf("Case #%d:
    ",++case1);
            while(m--)
            {
                scanf("%d%d",&x,&y) ;
                printf("%d
    ",solve(x,y)) ;
            }
        }
        return 0 ;
    }
    

      

  • 相关阅读:
    iOS 页面间几种传值方式(属性,代理,block,单例,通知)
    iOS CocoaPods安装与使用
    iOS UIWebView截获html并修改便签内容
    block的底层实现原理?
    多线程的底层实现是什么?
    tabviewcell的删除注意
    iOS9 新特性总结!!!
    类方法加Static -------不需要初始化变量
    Warning:whose view is not in the window herarchy!
    iOS----录音:真机调试的注意
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/4071484.html
Copyright © 2011-2022 走看看