2020暑期集训 week2

训练内容:

1场cf,1场eoj月赛,2场牛客多校,9个cf上难度1600-2000的题


推荐题目:

F2. The Hidden Pair (Hard Version)

交互题,https://codeforces.com/contest/1370/problem/F2一开始就有思路。
首先找所有的点,输出一定是 这条路径中的一个点 和 这条路径的长度
然后我们以已知的这个点为根dfs,记录每层有什么点。
假设路径长度为k,答案之一距离根的max肯定大于等于(k+1)/2,我们就先找这个远的点。
下界为(k+1)/2,上界为k,二分查找即可。
得到这个点之后,再以这个点为根,那么距离这个点k距离的点集中再查询一次,即可得到另一个点

在这里插入图片描述

int n,m;
char str[N];
int f[M];
vector<int> v[M],lvl[M],tmp;
pt query(vector<int> &tt)
{
    if(!tt.size()) return mp(-1,-1);
    cout<<"? "<<tt.size();
    for(int x:tt) cout<<" "<<x;
    cout<<endl;
    int a,b;
    cin>>a>>b;
    return mp(a,b);
}
void dfs(int x,int fa,int dep)
{
    m=max(m,dep);
    lvl[dep].pb(x);
    for(int y:v[x]){
        if(y!=fa){
            dfs(y,x,dep+1);
        }
    }
}
int main()
{
    int t;r(t);
    while(t--){
        r(n);
        m=0;
        tmp.clear();
        lvl[0].clear();
        FOR(i,1,n){
            v[i].clear();
            lvl[i].clear();
            tmp.pb(i);
        }
        FOR(i,1,n-1){
            int a,b;rr(a,b);
            v[a].pb(b);
            v[b].pb(a);
        }
        pt res=query(tmp);
        int root=res.fi,dep=res.se;
        dfs(root,0,0);
        int l=(dep+1)/2,r=min(m,dep),ans1;
        while(l<=r){
            int mid=l+r>>1;
            res=query(lvl[mid]);
            if(res.se==dep){
                ans1=res.fi;
                l=mid+1;
            }
            else r=mid-1;
        }
        FOR(i,0,n) lvl[i].clear();
        dfs(ans1,0,0);
        res=query(lvl[dep]);
        cout<<"! "<<ans1<<' '<<res.fi<<endl;
        string s;
        cin>>s;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值