P7124 Ynoi2008 stcm

P7124 Ynoi2008 stcm

妙妙构造。

思路

求出树的 dfn 序,进行分治,对于 [1,n] 分治为,[1,n21][n2+1,n] 两段,若存在一个子树 [l,r] 包括点 n2 且没有标记过,就加入 [l,r] 的补集,并标记子树 [l,r]

每次处理的是 n2 的祖先,所以将 l 升序排序,先处理较上的祖先,补集可以继承父亲的部分。

进入下一段前,删除该段在集合中的部分并将该段的补集全部加入集合。

退出这一段时清除自己在集合中的部分。

命令次数是 nlogn 级的,带一点常数。

CODE

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+5;

struct Edge
{
    int tot;
    int head[maxn];
    struct edgenode{int to,nxt;}edge[maxn*2];
    inline void add(int x,int y)
    {
        tot++;
        edge[tot].to=y;
        edge[tot].nxt=head[x];
        head[x]=tot;
    }
}T;

int n,cok;
int dfn[maxn],ed[maxn],fdfn[maxn];

vector<int>vec;

inline void clr()
{
    for(int i=1;i<=n;i++) T.head[i]=dfn[i]=ed[i]=fdfn[i]=0;
    T.tot=cok=0;
    vec.clear();
}
inline void dfs(int u)
{
    ed[u]=dfn[u]=++cok;fdfn[cok]=u;
    vec.push_back(dfn[u]);
    for(int i=T.head[u];i;i=T.edge[i].nxt)
    {
        int v=T.edge[i].to;
        dfs(v);
        ed[u]=ed[v];
    }
}
inline void solve(int l,int r)
{
    vector<int>lv,rv;
    int ld=l-1,rd=r+1,mid=(l+r)>>1,cnt=0;
    for(auto v:vec)
    {
        if(ed[fdfn[v]]<mid) lv.push_back(v);
        else if(v>mid) rv.push_back(v);
        else
        {
            while(ld<v-1) printf("+%d",fdfn[++ld]),cnt++;
            while(rd>ed[fdfn[v]]+1) printf("+%d",fdfn[--rd]),cnt++;
            printf("=%d",fdfn[v]);
        }
    }
    if(l==r) return ;
    for(int i=1;i<=cnt;i++) printf("-");
    if(l==r) return ;
    for(int i=l;i<=mid;i++) printf("+%d",fdfn[i]);
    swap(vec,rv);
    solve(mid+1,r);
    for(int i=l;i<=mid;i++) printf("-");
    for(int i=mid+1;i<=r;i++) printf("+%d",fdfn[i]);
    swap(vec,lv);
    solve(l,mid);
    for(int i=mid+1;i<=r;i++) printf("-");
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        clr();
        for(int i=1;i<n;i++)
        {
            int u;
            scanf("%d",&u);
            T.add(u,i+1);
        }
        dfs(1);
        sort(vec.begin(),vec.end());
        solve(1,n);
        printf("!\n");
    }
}

posted @   彬彬冰激凌  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示