UOJ Logo Ring的博客

博客

求助神奇代码

2022-07-30 20:00:22 By Ring

模拟赛题不方便公开。就是普通的全局平衡二叉树建树

NOIlinux 和 UOJ 上“这里”使用现在的写法会使得 t[2].fa = 2,但换成 t[rs(u)=bld(l,i-1)].fa = u, t[ls(u)=bld(i+1,r)].fa = u; 就对了
CF 上两种写法都能过

查不出 UB/RE,求教啥情况啊 /kk

#include <bits/stdc++.h>
using namespace std;
#define For(i,x,y,...) for(int i=x,##__VA_ARGS__;i<=(y);++i)
#define Rep(i,x,y,...) for(int i=x,##__VA_ARGS__;i<(y);++i)
#define pb emplace_back
typedef vector<int> Vi;

const int N = 1e6+5;
int n;

    int fa[N],dep[N],siz[N],son[N],top[N],id[N];
    Vi e[N];
    #define ls(u) t[u].ch[0]
    #define rs(u) t[u].ch[1]
    struct { int ch[2],fa; } t[N];
    int bld(int l,int r) {
        if( l > r ) return 0;
        auto w=[&](int u) { return siz[u]-siz[son[u]]; };
        int s=0; For(i,l,r) s += w(id[i]);
        For(i,l,r, x = 0) {
            x += w(id[i]);
            if( x+x >= s ) {
                int u = id[i];
                t[rs(u)=bld(l,i-1)].fa = t[ls(u)=bld(i+1,r)].fa = u; // 这里
                return u;
            }
        }
        assert(0);
    }
    #undef ls
    #undef rs
    void dfs1(int u) {
        dep[u] = dep[fa[u]]+1, siz[u] = 1;
        for(int v : e[u]) {
            fa[v] = u, dfs1(v), siz[u] += siz[v];
            if( siz[v] > siz[son[u]] ) son[u] = v;
        }
    }
    void dfs2(int u,int t) {
        top[u] = t;
        if( !son[u] ) {
            int ind=0; for(int i = u; top[i] == t; i = fa[i]) id[++ind] = i;
            bld(1,ind);
        } else dfs2(son[u],t);
        for(int v : e[u]) if( v != son[u] ) dfs2(v,v);
    }

signed main() { freopen("in","r",stdin); freopen("elixir.out","w",stdout);
    cin>>n; Rep(i,1,n, x,y) cin>>x>>y, e[x].pb(y);
    dfs1(1), dfs2(1,1);
    For(i,1,n) cout<<t[i].fa<<' ';
    return 0;
}
/*
in:
7
1 2
1 7
2 3
3 4
4 5
5 6
out:
3 1 0 5 3 5 0 
*/

upd 1

不知道是不是数据小,t[ls(u)=bld(i+1,r)].fa = t[rs(u)=bld(l,i-1)].fa = u; 也能过

Ring Avatar