zoukankan      html  css  js  c++  java
  • [机房测试]学园偶像的盛会

    Description

    (n) 个乐队,舞台构成一棵树。第 (i) 个乐队的名字叫 (s_i),会从第 (i) 个节点向上的所有 (y_i) 个节点依次巡演。对于一个点,假设其上有 (k) 支队伍要在此巡演,那么她们会按名字的字典序大小依次表演。(m) 个询问,每次询问乐队 (x)(k) 次表演之前是哪个乐队,输出名字,不存在输出 "none"。

    Solution

    对于一个乐队,在其初始位置打上加法标记,在结束位置的父亲打上减法标记。离线询问,丢到节点上。前面这部分预处理可以倍增优化。由于名字很短,直接使用自带的 strcmp 来快排,处理出排名。每个节点维护一棵主席树,答案实际上就是前驱。所以 dfs 一遍整棵树,处理每个点的询问,然后向上线段树合并即可。

    (O(nlog n)),题解写的是平衡树启发式合并,会多一个 (log),不太优秀。

    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    #include<string.h>
    using namespace std;
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    const int N=2e5+7;
    
    char s[N][14];
    int fa[N][17],a[N],head[N],n,m;
    
    struct Node{
        int sz,ls,rs;
    }t[N*20];
    
    struct E{
        int next,to;
    }e[N<<1];
    
    struct Query{int val,pos;};
    vector<int> C[N];
    vector<Query> Q[N];
    
    int ans[N],rk[N],Rk[N];
    
    inline void add(int id,int to){
        static int cnt=0;
        e[++cnt]=(E){head[id],to};
        head[id]=cnt;
        e[++cnt]=(E){head[to],id};
        head[to]=cnt;
    }
    
    void dfs(int u){
        for(int i=1;i<=16;i++)
            fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int i=head[u];i;i=e[i].next)
            if(e[i].to!=fa[u][0]) fa[e[i].to][0]=u,dfs(e[i].to);
    }
    
    inline void update(int id){
        t[id].sz=t[t[id].ls].sz+t[t[id].rs].sz;
    }
    
    int Pos;
    void modify(int &id,int lf,int rf){
        static int cnt=0;
        if(!id) id=++cnt;
        if(lf==rf) t[id].sz^=1;
        else{
            int mid=(lf+rf)>>1;
            if(Pos<=mid) modify(t[id].ls,lf,mid);
            else modify(t[id].rs,mid+1,rf);
            update(id);
        }
    }
    
    int merge(int x,int y,int lf,int rf){
        if(!x||!y) return x+y;
        if(lf==rf) t[x].sz+=t[y].sz;
        else{
            int mid=(lf+rf)>>1;
            t[x].ls=merge(t[x].ls,t[y].ls,lf,mid);
            t[x].rs=merge(t[x].rs,t[y].rs,mid+1,rf);
            update(x);
        }
        return x;
    }
    
    int query(int id,int lf,int rf){
        if(!id||!t[id].sz) return 0;
        if(lf==rf) return Rk[lf];
        int mid=(lf+rf)>>1;
        if(Pos<=mid) return query(t[id].ls,lf,mid);
        int ret=query(t[id].rs,mid+1,rf);
        if(ret) return ret;
        return query(t[id].ls,lf,mid);
    }
    
    int rt[N];
    void Dfs(int u){
        for(int i=head[u];i;i=e[i].next){
            const int v=e[i].to;
            if(v==fa[u][0]) continue;
            Dfs(v),rt[u]=merge(rt[u],rt[v],1,n);
        }
        for(int x:C[u])
            Pos=x,modify(rt[u],1,n);
        for(Query x:Q[u])
            Pos=x.val-1,ans[x.pos]=Pos? query(rt[u],1,n):0;
    }
    
    inline bool Cmp(int x,int y){
        return strcmp(s[x],s[y])==-1;
    }
    
    int main(){
        freopen("idol.in","r",stdin);
        freopen("idol.out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=n;i++)
            scanf("%s %d",s[i],&a[i]),Rk[i]=i;
        for(int i=2;i<=n;i++) add(read(),read());
        dfs(1),sort(Rk+1,Rk+1+n,Cmp);
        for(int i=1;i<=n;i++) rk[Rk[i]]=i;
        for(int i=1;i<=m;i++){
            int x=read(),y=read()-1,now=x;
            for(int j=16;~j;j--)
                if(y&(1<<j)) now=fa[now][j];
            if(!now||y+1>a[x]) continue;
            Q[now].push_back((Query){rk[x],i});
        }
        for(int i=1;i<=n;i++){
            C[i].push_back(rk[i]);
            int now=i;
            for(int j=16;~j;j--)
                if(a[i]&(1<<j)) now=fa[now][j];
            if(now) C[now].push_back(rk[i]);
        }
        Dfs(1);
        for(int i=1;i<=m;i++)
            printf("%s
    ",ans[i]? s[ans[i]]:"none");
    }
    
  • 相关阅读:
    每日一水 POJ8道水题
    编译和使用 MySQL C++ Connector
    j2ee model1模型完成分页逻辑的实现 详解!
    DB查询分析器访问EXCEL时,要在表名前后加上中括弧或双引号
    指向结构体变量的指针
    EOSS V3.0 企业运营支撑系统(基于RBAC原理的权限管理)
    MybatisGen1.0 Mybatis JavaBean Mapper生成工具
    The table name must be enclosed in double quotation marks or sqare bracket while accessing EXCEL by
    资源-Android:Android
    软件-开发软件:Android Studio
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15383880.html
Copyright © 2011-2022 走看看