• [机房测试]学园偶像的盛会


    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");
    }
    
  • 相关阅读:
    想你,却不能告诉你
    【缅怀妈妈系列诗歌】之十七:叩别妈妈
    80后的大旗正矗立在中华大地上迎风飘扬
    【缅怀妈妈系列诗歌】之九:月祭母亲
    【缅怀妈妈系列诗歌】之十一:妈妈,我们回家
    工欲善其事,必先利其器——图文并茂详解VisualStudio使用技巧二 (转)
    工欲善其事,必先利其器——图文并茂详解VisualStudio使用技巧一 (转)
    老婆,我会好好爱你的
    【缅怀妈妈系列诗歌】之十:妈妈,孩儿答应您
    【缅怀妈妈系列诗歌】之八:妈妈,我不会忘记
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15383880.html
Copyright © 2020-2023  润新知