zoukankan      html  css  js  c++  java
  • CF772E Verifying Kingdom

    CF772E Verifying Kingdom 

    有趣的交互题(交互题都挺有意思的)

    %ywy

    增量法构造

    考虑加入了前i个叶子

    那么树是前i个叶子构成的虚树!

    最后n个叶子构成的虚树就是答案!

    怎样确定第i+1个叶子的位置?

    用点分治“二分”!

    每次找到当前连通块的重心rt,注意rt不能是叶子

    维护rt的两个儿子,父亲,两个儿子内部随意一个叶子has[0],has[1]

    用has[0],has[1],i+1进行ask,X,Y,Z唯一确定一个方向:fa、rson,lson

    递归进去二分。

    边界:

    1.往fa走没有fa,新建

    2.往fa、son已经vis了,这个边上长出一个点和一个叶子来

    3.当前点是叶子,新建节点,叶子和i+1连在下面。

    询问次数O(nlogn)

    复杂度O(n^2)(每次现找重心,只递归一边。) 

    注意:

    1.点分治找到rt之后再dfs才是真正size。。

    2.rt和进入点x不能弄混了。。

    Code

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define numb (ch^'0')
    #define pb push_back
    #define solid const auto &
    #define enter cout<<endl
    #define pii pair<int,int>
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
    template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
    template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
    ');}
    namespace Modulo{
    const int mod=998244353;
    int ad(int x,int y){return (x+y)>=mod?x+y-mod:x+y;}
    void inc(int &x,int y){x=ad(x,y);}
    int mul(int x,int y){return (ll)x*y%mod;}
    void inc2(int &x,int y){x=mul(x,y);}
    int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
    }
    //using namespace Modulo;
    namespace Miracle{
    const int N=2005;
    int n;
    char s[233];
    int fa[N],ch[N][2],has[N][2];//has a leaf
    int tot;
    int ask(int a,int b,int c){
        printf("%d %d %d
    ",a,b,c);
        fflush(stdout);
        scanf("%s",s+1);
        return (s[1]-'X');
    }
    bool vis[N];
    int rt,sz[N];
    int nowsz;
    void dfs(int x,int od){
        if(!x) return;
        // cout<<" x "<<x<<" od "<<od<<" "<<fa[x]<<" "<<ch[x][0]<<" "<<ch[x][1]<<" visf "<<vis[fa[x]]<<" "<<(fa[x]!=od)<<endl;
        sz[x]=1;
        int mx=0,now;
        if(!vis[fa[x]]&&fa[x]!=od) dfs(fa[x],x),mx=max(mx,sz[fa[x]]),sz[x]+=sz[fa[x]];
        if(!vis[ch[x][0]]&&ch[x][0]!=od) dfs(ch[x][0],x),mx=max(mx,sz[ch[x][0]]),sz[x]+=sz[ch[x][0]];
        if(!vis[ch[x][1]]&&ch[x][1]!=od) dfs(ch[x][1],x),mx=max(mx,sz[ch[x][1]]),sz[x]+=sz[ch[x][1]];
        
    
        if((ch[x][0]||ch[x][1])&&(max(mx,nowsz-sz[x])<=nowsz/2)) rt=x;
    }
    void dfs2(int x,int od){
        if(!x) return;
        // cout<<" x "<<x<<" od "<<od<<" "<<fa[x]<<" "<<ch[x][0]<<" "<<ch[x][1]<<" visf "<<vis[fa[x]]<<" "<<(fa[x]!=od)<<endl;
        sz[x]=1;
        if(!vis[fa[x]]&&fa[x]!=od) dfs2(fa[x],x),sz[x]+=sz[fa[x]];
        if(!vis[ch[x][0]]&&ch[x][0]!=od) dfs2(ch[x][0],x),sz[x]+=sz[ch[x][0]];
        if(!vis[ch[x][1]]&&ch[x][1]!=od) dfs2(ch[x][1],x),sz[x]+=sz[ch[x][1]];
    }
    void fin(int x,int id){
        // cout<<" fin "<<x<<" nowsz "<<nowsz<<endl;
        if(!ch[x][0]&&!ch[x][1]){//leaf
            // cout<<" leaf "<<endl;
            ++tot;
            int d=ch[fa[x]][1]==x;
            ch[tot][0]=x;ch[tot][1]=id;fa[tot]=fa[x];ch[fa[x]][d]=tot;
            fa[x]=tot;fa[id]=tot;
            has[tot][0]=x;has[tot][1]=id;
            return ;
        }
        rt=0;
        dfs(x,0);
        x=rt;
        dfs2(rt,0);
        // cout<<" rt "<<rt<<" has "<<has[rt][0]<<" "<<has[rt][1]<<endl;
        int bc=ask(has[rt][0],has[rt][1],id);
        vis[rt]=1;
        if(bc==0){
            if(fa[x]){
                if(vis[fa[x]]){
                    int y=fa[x];
                    int d=ch[y][1]==x;
                    ch[y][d]=++tot;
                    fa[tot]=y;
                    ch[tot][d]=x;fa[x]=tot;
                    ch[tot][d^1]=id;
                    fa[id]=tot;
                    has[tot][d]=has[x][0];
                    has[tot][d^1]=id;
                }else{
                    nowsz=sz[fa[x]];
                    fin(fa[x],id);
                }
            }else{
                // cout<<" nofa "<<endl;
                fa[x]=++tot;
                ch[tot][0]=x;
                ch[tot][1]=id;
                has[tot][0]=has[x][0];
                has[tot][1]=id;
                fa[id]=tot;
            }
        }else {
            int p;
            if(bc==1) p=1;
            else p=0;
            if(ch[x][p]){
                int z=ch[x][p];
                // cout<<" z "<<z<<endl;
                if(vis[z]){
                    ++tot;
                    ch[x][p]=tot;fa[tot]=x;
                    ch[tot][p]=z;fa[z]=tot;
                    ch[tot][p^1]=id;fa[id]=tot;
                    has[tot][p^1]=id;
                    has[tot][p]=has[z][0];
                }else{
                    nowsz=sz[z];
                    fin(z,id);
                }
            }else{ 
                assert(-1>0);
            }
        }
    }
    int main(){
        rd(n);
        tot=n;
        ++tot;
        has[tot][0]=ch[tot][0]=1;fa[1]=tot;
        has[tot][1]=ch[tot][1]=2;fa[2]=tot;
        for(reg i=3;i<=n;++i){
            // cout<<"ii ----------------------- "<<i<<endl;
            memset(vis,0,sizeof vis);
            memset(sz,0,sizeof sz);
            // for(reg j=1;j<i;++j) vis[j]=1;
            nowsz=2*(i-1)-1;
            // cout<<" vis[55] "<<vis[55]<<endl;
            fin(tot,i);
            // for(reg i=1;i<=tot;++i){
            //     cout<<i<<" : fa "<<fa[i]<<" ls "<<ch[i][0]<<" rs "<<ch[i][1]<<" hasls "<<has[i][0]<<" hasrs "<<has[i][1]<<endl;
            // }
        }
        // prt(fa,1,tot);
        printf("-1
    ");
        for(reg i=1;i<=tot;++i){
            if(!fa[i]) fa[i]=-1;
            ot(fa[i]);
        }
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
    */

    交互题都是要找到一个方向去构造的

    比如这个就是增量构造

    10*n,类似nlogn,二分?

    考虑定位,发现点分治最合适了。

  • 相关阅读:
    Cygwin 与 MinGW/MSYS/MSYS2,如何选择?甚至还有GNU utilities for Win32
    MinGW和MSYS项目是在一起的(翻译官网)
    库存限购
    ElasticSearch指南
    Windows系统的Jenkins持续集成环境
    JavaScript 框架
    Istio Service Mash管理微服务
    LinkedIn微服务框架rest.li
    Istio微服务架构初试
    github
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10981909.html
Copyright © 2011-2022 走看看