编程介的小学生 2017-11-17 04:20 采纳率: 20.5%
浏览 603
已结题

The LCIS on the Tree

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

  • 写回答

1条回答 默认 最新

  • HHi3s 2018-08-03 21:45
    关注
    #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:\n",++case1);
            while(m--)
            {
                scanf("%d%d",&x,&y) ;
                printf("%d\n",solve(x,y)) ;
            }
        }
        return 0 ;
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题