#include<bits/stdc++.h> #define reg register int #define il inline #define mid ((l+r)>>1) #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;x=0;bool fl=fals

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define mid ((l+r)>>1)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1e6+6;
const int M=4e6+5;
int n;
int b[N][2];
int a[N],I;
int ori[N];
ll k;
int hd[N],cnt;
int bian[N][2];
struct node{
    int nxt,to;
}e[2*N];
void addedge(int x,int y){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    hd[x]=cnt;
}
ll mul(ll a,ll b){
    return (long double)a*(long double)b>(long double)k+1?k+2:a*b;
}
ll add(ll a,ll b){
    return a+b>k+1?k+2:a+b;
}
struct mat{
    ll a[2][2];
    void clear(){memset(a,0,sizeof a);}
    void pre(){a[0][0]=1;a[1][1]=1;a[0][1]=a[1][0]=0;}
    void init(){a[0][0]=a[1][0]=a[0][1]=1;a[1][1]=0;}
    mat operator *(const mat&b){
        mat c;c.clear();
//        for(reg i=0;i<1;++i){
//            for(reg k=0;k<1;++k){
//                for(reg j=0;j<1;++j){
//                    c.a[i][j]=add(c.a[i][j],mul(a[i][k],b.a[k][j]));
//                }
//            }
//        }
        c.a[0][0]=add(mul(a[0][0],b.a[0][0]),mul(a[0][1],b.a[1][0]));
        c.a[0][1]=add(mul(a[0][0],b.a[0][1]),mul(a[0][1],b.a[1][1]));
        c.a[1][0]=add(mul(a[1][0],b.a[0][0]),mul(a[1][1],b.a[1][0]));
        c.a[1][1]=add(mul(a[1][0],b.a[0][1]),mul(a[1][1],b.a[1][1]));
        return c;
    }
    void op(){
        cout<<a[0][0]<<" "<<a[0][1]<<endl;
        cout<<a[1][0]<<" "<<a[1][1]<<endl;
    }
}st[N],base,nowdp;

int dfn[N],top[N],dep[N],son[N],sz[N],fa[N];
int fdfn[N];
int low[N];
int df;
int totson[N];
int num[N];//i is i's fa's num[i] son
int in[N];//0 not 1 yes
ll f[N][2];

namespace seg1{//get lian
int tot;
int ls[M],rs[M];
mat data[M];
struct tr1{
    int ss,nd;
    int rt;
    void pushup(int x){
    //    cout<<"pushup "<<x<<" "<<ls[x]<<" "<<rs[x]<<endl;
    //    data[rs[x]].op();
    //    data[ls[x]].op();
        data[x]=data[rs[x]]*data[ls[x]];
    //    cout<<endl;
    //    data[x].op();
    }
    mat get(){
        return data[rt];
    }
    void build(int &x,int l,int r){
        x=++tot;
    //    cout<<" x "<<x<<" "<<l<<" "<<r<<endl;
        if(l==r){
        //    cout<<"l==r "<<fdfn[l]<<endl;
        //    st[fdfn[l]].op();
            data[x]=st[fdfn[l]];return;
        }
        build(ls[x],l,mid);build(rs[x],mid+1,r);
        pushup(x);
    //    cout<<" bac "<<x<<" "<<endl;
    //    data[x].op();
    }
    void chan(int p,ll c0,ll c1){
        upda(rt,ss,nd,p,c0,c1);
    }
    mat que(int L,int R){
        return query(rt,ss,nd,L,R);
    }
    mat query(int x,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return data[x];
        }
        mat ret;
        ret.pre();
        if(mid<R) ret=ret*query(rs[x],mid+1,r,L,R);
        if(L<=mid) ret=ret*query(ls[x],l,mid,L,R);
        return ret;
    }
    void upda(int x,int l,int r,int p,ll c0,ll c1){
        if(l==r){
            data[x].a[0][0]=c0;
            data[x].a[1][0]=c0;
            data[x].a[0][1]=c1;
            return;
        }
        if(p<=mid) upda(ls[x],l,mid,p,c0,c1);
        else upda(rs[x],mid+1,r,p,c0,c1);
        pushup(x);
    }
};

}using seg1::tr1;
tr1 t1[N];

int mem[N];
namespace seg2{//get son
int tot;
int ls[M],rs[M];
ll s0[M],s1[M];
struct tr2{
    int sz,rt;
    void pushup(int x){
        s0[x]=mul(s0[ls[x]],s0[rs[x]]);
        s1[x]=mul(s1[ls[x]],s1[rs[x]]);
    }
    void build(int &x,int l,int r){
        x=++tot;
        if(l==r){
            s0[x]=f[mem[l]][0]+f[mem[l]][1];
            s1[x]=f[mem[l]][0];
            return;
        }
        build(ls[x],l,mid);build(rs[x],mid+1,r);
        pushup(x);
    }
    void chan(int p,ll c0,ll c1){
        upda(rt,1,sz,p,c0,c1);
    }
    void upda(int x,int l,int r,int p,ll c0,ll c1){
        if(l==r){
            s0[x]=c0;
            s1[x]=c1;
            return;
        }
        if(p<=mid) upda(ls[x],l,mid,p,c0,c1);
        else upda(rs[x],mid+1,r,p,c0,c1);
        pushup(x);
    }
    void spe(int &x){
        x=++tot;
        s0[x]=1;s1[x]=1;
    }
    ll get0(){
    //    cout<<" rtrt "<<rt<<endl;
        return s0[rt];
    }
    ll get1(){
        return s1[rt];
    }
};

}using seg2::tr2;
tr2 t2[N];

int sta[N],tp;
void dfs1(int x,int d){
//    cout<<"dfs1 "<<x<<" "<<d<<endl;
    dep[x]=d;
    sz[x]=1;
    if(!in[x])f[x][0]=1;
    else f[x][1]=1;
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa[x]) continue;
        fa[y]=x;
        dfs1(y,x);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]]) son[x]=y;
    }
}
void dfs2(int x){
//    cout<<" dfs2 "<<x<<" "<<son[x]<<endl;
    dfn[x]=++df;
    sta[++tp]=x;
    fdfn[df]=x;
    if(!top[x]) top[x]=x;
    if(son[x]) top[son[x]]=top[x],++totson[x],dfs2(son[x]);
    st[x].init();
    
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==son[x]) continue;
        if(y==fa[x]) continue;
        num[y]=totson[x];
        ++totson[x];
        dfs2(y);
        if(in[x]){
            st[x].a[0][1]*=(f[y][0]);
        }else{
            st[x].a[0][0]*=(f[y][0]+f[y][1]);
            st[x].a[1][0]*=(f[y][0]+f[y][1]);
        }
    }
    if(in[x]) st[x].a[0][0]=st[x].a[1][0]=0;
    else st[x].a[0][1]=0;
//    cout<<" mat-------------------------------"<<x<<endl;
    //st[x].op();
    
//        t1[top[x]].ss=dfn[top[x]];
//        t1[top[x]].nd=dfn[x];
//        t1[top[x]].build(t1[top[x]].rt,t1[top[x]].ss,t1[top[x]].nd);
//        
        
    if(top[x]==x){    
    //    cout<<" zhong ss "<<x<<" nd "<<sta[tp]<<endl;
        t1[x].ss=dfn[x];
        t1[x].nd=dfn[sta[tp]];
        t1[x].build(t1[x].rt,t1[x].ss,t1[x].nd);
    //    cout<<" t1rt "<<endl;t1[x].get().op();
        int z;
        do{
            z=sta[tp];
            --tp;
        }while(z!=x);
    }
    
    if(totson[x]==0){//leaf 
    
    
        t2[x].spe(t2[x].rt);    
    //    cout<<"gen "<<t2[x].rt<<endl;
    }
    else if(totson[x]==1){
        t2[x].spe(t2[x].rt);
        
    }
    else if(totson[x]>1){
    //    cout<<" has son "<<x<<" "<<totson[x]<<endl;
        int lp=0;
        for(reg i=hd[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(y==fa[x]||y==son[x]) continue;
            mem[++lp]=y;
        }
        t2[x].sz=lp;
        t2[x].build(t2[x].rt,1,lp);
    }
}
mat upda(int x){
    mat ret;
    ret.clear();
    cout<<" upda "<<x<<" in "<<in[x]<<endl;
    while(x){
        if(in[x]==0){//must not
            cout<<"get0 "<<t2[x].rt<<" "<<t2[x].get0()<<endl;
            t1[top[x]].chan(dfn[x],t2[x].get0(),0);
        }else if(in[x]==1){//must yes
            t1[top[x]].chan(dfn[x],0,t2[x].get1());
        }else{//either
            cout<<" g0 g1 "<<t2[x].get0()<<" "<<t2[x].get1()<<endl;
            t1[top[x]].chan(dfn[x],t2[x].get0(),t2[x].get1());
        }
        if(x==1)t1[top[x]].que(2,3).op(),t1[top[x]].que(1,1).op();
        cout<<" difd "<<endl;
        t1[top[x]].get().op();
        ret=base*t1[top[x]].get();
        x=top[x];
        if(fa[x]){
            t2[fa[x]].chan(num[x],add(ret.a[0][0],ret.a[0][1]),ret.a[0][0]);
        }
        x=fa[x];
    }
    cout<<"ret "<<ret.a[0][0]<<" "<<ret.a[0][1]<<endl;
    return ret;
}
int main(){
    rd(n);
    scanf("%lld",&k);
    base.a[0][0]=1;
    
    for(reg i=1;i<n;++i) rd(b[i][0]),++b[i][0];
    for(reg i=1;i<n;++i) {
        rd(b[i][1]);
        ++b[i][1];
        addedge(b[i][0],b[i][1]);
        addedge(b[i][1],b[i][0]);
    }
    rd(I);
    for(reg i=1;i<=I;++i) rd(a[i]),++a[i],in[a[i]]=1,ori[a[i]]=1;
    sort(a+1,a+I+1);
    
    if(k==0){
        for(reg i=1;i<=I;++i){
            printf("%d ",a[i]-1);
        }
        return 0;
    }
    dfs1(1,1);
    cout<<" after dfs1 "<<endl;
    dfs2(1);
    cout<<" after dfs2 "<<endl;
//    cout<<nowdp.a[0][0]+nowdp.a[0][1]<<endl;
    
    int lcp=I;//warning!! num 
    ll remain=k;
    for(reg i=a[lcp]+1;i<=n;++i){
        in[i]=2;
        nowdp=upda(i);
    }
    ll tot=add(nowdp.a[0][0],nowdp.a[0][1]);
    int lp=0;
    //has=0;
    cout<<" after last zero "<<endl;
    if(tot-1<remain){
        remain-=tot-1;
        int ptr=a[lcp]-1;
        for(;lcp;--lcp){
            cout<<"lcp "<<lcp<<endl;
            in[a[lcp]]=0;
            nowdp=upda(a[lcp]);
            tot=add(nowdp.a[0][0],nowdp.a[0][1]);
            cout<<"tot "<<tot<<endl;
            if(tot-1<remain){
                remain-=tot-1;
                in[a[lcp]]=2;
                nowdp=upda(a[lcp]);
            }else{
                break;
            }
            ptr=a[lcp]-1;
            while(ptr&&ori[ptr]!=1){
                in[ptr]=2;
                nowdp=upda(ptr);
                --ptr;
            }
        }
        if(!lcp){
            return 0;
        }
    }
    cout<<" after lcp "<<lcp<<endl;
//    else{
//        lp=a[lcp]+1;
//        for(reg i=lp;i<=n;++)
//    }
    lp=a[lcp]+1;
    for(reg i=lp;i<=n;++i){
        cout<<" ii "<<i<<" ---------------- "<<endl;
        in[i]=1;
        nowdp=upda(i);
        tot=add(nowdp.a[0][0],nowdp.a[0][1]);
        cout<<" tot "<<tot<<endl;
        if(tot<remain){
            remain-=tot;
            in[i]=0;
            nowdp=upda(i);
        }else{
            --remain;
        }
    }
    for(reg i=1;i<=n;++i){
        if(in[i]){
            printf("%d ",i-1);
        }
    }
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/2/20 11:04:52
*/

4
2
0 0 2
1 2 3
2
0 3

 

猜你喜欢

转载自www.cnblogs.com/Miracevin/p/10415744.html