zoukankan      html  css  js  c++  java
  • COGS 2280. [HZOI 2015]树白黑

    ★★   输入文件:B_Tree.in   输出文件:B_Tree.out   简单对比
    时间限制:2 s   内存限制:512 MB

    【题目描述】

    给定一棵有根树,树根为1,一开始这棵树所有节点均为白色

    之后给定一个染色序列,第i个数ai表示将ai这个点染黑

    之后给定若干询问

    询问第L到第R个染黑的黑点和u所有的LCA中深度最大的LCA的编号

    【输入格式】

    第一行n,m,q 表示节点总数,染色序列长度,询问个数

    以下n-1行,每行u,v描述一条边的两个端点

    之后m个正整数表示染色序列

    之后q行,每行L,R,u 如题目所示

    n,m,q<=200000 可能会有点重复被染色

    【输出格式】

    对于每个询问输出对应的答案

    【样例输入】

    5 5 5
    1 2
    2 3
    3 4
    1 5
    3 2 4 3 2
    3 5 4
    1 2 1
    1 1 2
    5 5 2
    2 2 4
    

    【样例输出】

    4
    1
    2
    2
    2


    主席树+LCA
    屠龙宝刀点击就送
    #include <cstdio>
    #include <vector>
    #define N 200500
    
    using std::vector;
    vector<int>edge[N];
    struct cmt
    {
        int l,r,Size;
    }tr[N*30];
    int k,tot,tim,n,m,q,root[N],siz[N],dad[N][25],dfn[N],pos[N],dep[N];
    void dfs(int x)
    {
        dfn[x]=++tim;
        pos[tim]=x;
        dep[x]=dep[dad[x][0]]+1;
        for(int i=0;dad[x][i];i++)
        dad[x][i+1]=dad[dad[x][i]][i];
        for(int i=0;i<edge[x].size();++i)
        {
            int v=edge[x][i];
            if(dad[x][0]!=v)
            {
                dad[v][0]=x;
                dfs(v);
            }
        }
    }
    void update(int l,int r,int x,int &y,int t)
    {
        y=++tot;
        tr[y].Size=tr[x].Size+1;
        if(l==r) return;
        tr[y].l=tr[x].l;
        tr[y].r=tr[x].r;
        int mid=(l+r)>>1;
        if(t<=mid) update(l,mid,tr[x].l,tr[y].l,t);
        else update(mid+1,r,tr[x].r,tr[y].r,t);
    }
    int ask(int l,int r,int lx,int rx)
    {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(k<=tr[tr[rx].l].Size-tr[tr[lx].l].Size) return ask(l,mid,tr[lx].l,tr[rx].l);
        else {k-=tr[tr[rx].l].Size-tr[tr[lx].l].Size;return ask(mid+1,r,tr[lx].r,tr[rx].r);} 
    }
    int query(int l,int r,int x,int y,int a,int b)
    {
        if(l==a&&r==b) return tr[y].Size-tr[x].Size;
        int mid=(l+r)>>1;
        if(a>mid) return query(mid+1,r,tr[x].r,tr[y].r,a,b);
        else if(b<=mid) return query(l,mid,tr[x].l,tr[y].l,a,b);
        else return query(l,mid,tr[x].l,tr[y].l,a,mid)+query(mid+1,r,tr[x].r,tr[y].r,mid+1,b);
    }
    inline void swap(int &m,int &n)
    {
        int tmp=n;
        n=m;
        m=tmp;
    }
    inline int lca(int x,int y)
    {
        if(dep[x]>dep[y]) swap(x,y);
        for(int i=20;i>=0;i--)
        if(dep[dad[y][i]]>=dep[x]) y=dad[y][i];
        if(x==y) return x;
        for(int i=20;i>=0;i--)
        if(dad[x][i]!=dad[y][i]) x=dad[x][i],y=dad[y][i];
        return dad[x][0];
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&q);
        for(int u,v,i=1;i<n;++i)
        {
            scanf("%d%d",&u,&v);
            edge[u].push_back(v);
            edge[v].push_back(u);  
        }
        dfs(1);
        for(int a,i=1;i<=m;++i)
        {
            scanf("%d",&a);
            update(1,n,root[i-1],root[i],dfn[a]);
        }
        for(int l,r,u;q--;)
        {
            scanf("%d%d%d",&l,&r,&u);
            if(dfn[u]==1)
            {
                k=1;
                printf("%d
    ",lca(u,pos[ask(1,n,root[l-1],root[r])]));
            }
            else if(dfn[u]==n)
            {
                k=r-l+1;
                printf("%d
    ",lca(u,pos[ask(1,n,root[l-1],root[r])]));
            }
            else
            {
                int tmp=query(1,n,root[l-1],root[r],1,dfn[u]-1);
                if(tmp)
                {
                    k=tmp;
                    int x=pos[ask(1,n,root[l-1],root[r])];
                    if(tmp==r-l+1) printf("%d
    ",lca(u,x));
                    else
                    {
                        k=tmp+1;
                        int y=pos[ask(1,n,root[l-1],root[r])];
                        x=lca(x,u);
                        y=lca(y,u);
                        printf("%d
    ",dep[x]>dep[y]?x:y);
                    }
                }
                else k=1,printf("%d
    ",lca(u,pos[ask(1,n,root[l-1],root[r])]));
            }
        }
        return 0;
    }
    
    
    
     
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    visio画UML用例图没有include关系的解决方法
    个人推荐-几款好用的App
    win10锁屏壁纸文件夹Assets中无文件问题的解决方法
    云服务器搭建Jupyter-主要部分为配置服务器安全组+添加python3
    开通博客的第一天
    express学习(二)—— Post()类型和中间件
    自定义模块
    命名参数名(含*args , * *kw的区别)
    Python学习之中文注释问题
    Python学习之再议row_input
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7406884.html
Copyright © 2011-2022 走看看