LOJ # 6669 Nauuo and Binary Tree (interactive title, tree chain split)

Topic Link

https://loj.ac/problem/6669

answer

Orz yyf too god, out of this good and interesting questions have meaningful benefit of mankind ......
First \ (n \) times the depth of inquiry determined that all nodes.
Considered for depth expansion (the BFS), while maintaining a heavy chain split
at each expansion point, starting from the root node of the heavy chain, each query from the current node to the chain of the end node, so they can calculate the depth of the LCA, that is the path to the current node to the root portion and the maximum depth which intersects the heavy chains. So if the maximum depth equal to the current depth \ (--1 \) , we get the father of the point; otherwise skip LCA son's light on the heavy chain, continue to ask.
Time complexity \ (O (^ n-2) \) , the number of query \ (O (n-\ log n-) \) .

Code

Better than I imagined write.

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

inline int read()
{
    int x = 0,f = 1; char ch = getchar();
    for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
    return x*f;
}

const int N = 3000;
int son[N+3][2];
int hvs[N+3];
int dep[N+3];
int fa[N+3];
int sz[N+3];
vector<int> idep[N+3];
int n;

int getbtn(int u) {while(son[u][hvs[u]]) {u = son[u][hvs[u]];} return u;}
int jumpup(int u,int x) {while(x--) {u = fa[u];} return u;}
int jumpdown(int u,int x) {while(x--) {u = son[u][hvs[u]];} return u;}
void verify(int u) {hvs[u] = (sz[son[u][1]]>sz[son[u][0]]);}
void setfa(int u,int v) //fa[u]=v
{
//  printf("setfa %d %d\n",u,v);
    fa[u] = v; sz[u] = 1; son[v][son[v][0]?1:0] = u;
    while(v)
    {
        verify(v); sz[v]++; v = fa[v];
    }
}

void work(int u)
{
    int v = getbtn(1);
    while(1)
    {
        printf("? %d %d\n",v,u); fflush(stdout);
        int dis; scanf("%d",&dis);
        int deplca = (dep[u]+dep[v]-dis)>>1;
        v = jumpup(v,dep[v]-deplca);
        if(dep[u]-deplca==1) {setfa(u,v); return;}
        v = son[v][hvs[v]^1]; v = getbtn(v);
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=2; i<=n; i++) {printf("? %d %d\n",1,i); fflush(stdout); scanf("%d",&dep[i]); idep[dep[i]].push_back(i);}
    for(int i=0; i<idep[1].size(); i++) {setfa(idep[1][i],1);}
    for(int i=2; i<=n; i++)
    {
        for(int j=0; j<idep[i].size(); j++)
        {
            int u = idep[i][j];
            work(u);
        }
    }
    printf("! "); for(int i=2; i<=n; i++) printf("%d ",fa[i]); puts(""); fflush(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/suncongbo/p/12070871.html