https://codeforces.com/contest/1061/problem/F

题意

假设存在一颗完全k叉树(n<=1e5),允许你进行最多(n*60)次询问,然后输出这棵树的根,每次询问,a,b,c三个点,会返回b是否在a,c之间的路径上

思路

  • 粗略看了下询问次数,可以知道,你最多可以询问60对不同的点,每对点遍历n个点,可以知道n个点在不在这两个点的中间
  • 一开始的思路是,随机找两个点,遍历所有点,然后记录在他们中间的点,在里面再找两个点,继续上述操作,知道剩下一个点,但是假设某一步挑出的两个点的路径不经过根节点,hack
  • 假设树根在第0层,根据完全k叉树的性质,前k-1层点数为\(2^k-1\),第k层点数为\(2^k\),所以大约就是1:1,那么每次问出一个点是否为叶子的概率是1/2,所以可以先找出两个叶子,然后再询问出两个叶子的路径,中间的点就是根节点
  • 叶子结点怎么找:将叶子节点作为中间的点,随便找一个另外一个节点,那么叶子结点不在这个节点和其他节点的路径上,询问次数n

规律

  • 完全k叉树,叶子:非叶子 约等于 1:1
  • 生成随机数后加一个质数再取模,会使数据更加离散,
  • 树的叶子十分重要
  • 交互题一定要优化到最简询问次数,不然很容易被hack
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
char s[10];
int n,k,d,a,b,vi[2000],i,cnt;
vector<int>p,P; int pw(int bs,int x){
int ans=1;
while(x){
if(x&1)ans*=bs;bs*=bs;x>>=1;
}
return ans;
} void op(int a,int b,int x){
vector<int>tp;
memset(vi,0,sizeof(vi));
int cnt=0;
for(int i=1;i<=n;i++){
if(a==i||b==i)continue;
printf("? %d %d %d\n",a,i,b);
fflush(stdout);
scanf("%s",s);
if(s[0]=='Y'){vi[i]=1;cnt++;}
if(x==0&&cnt==2*d-3)break;
if(x&&cnt>d-2)break;
}
for(int i=1;i<=n;i++)if(vi[i])tp.pb(i);
if(x==0)P=tp;
else p=tp;
} int main(){
scanf("%d %d",&n,&k);
for(d=1;;d++)if((pw(k,d)-1)/(k-1)==n)break;
for(;;){
a=(rand()+4399)%n+1;b=(rand()+2755)%n+1;
if(a==b){b++;b=b%n+1;}
op(a,b,0);
if(P.size()==2*d-3)break;
}
for(i=0;i<P.size();i++){
op(P[i],a,1);
if(p.size()==d-2){
printf("! %d\n",P[i]);
fflush(stdout);
return 0;
}
}
}

Codeforces Round #523 (Div. 2) F. Katya and Segments Sets (交互题+思维)的更多相关文章

  1. Codeforces Round #524 (Div. 2) F. Katya and Segments Sets(主席树)

    https://codeforces.com/contest/1080/problem/F 题意 有k个区间,区间的种类有n种,有m个询问(n,m<=1e5,k<=3e5),每次询问a,b ...

  2. Codeforces Round #350 (Div. 2) F. Restore a Number 模拟构造题

    F. Restore a Number   Vasya decided to pass a very large integer n to Kate. First, he wrote that num ...

  3. Codeforces Round #496 (Div. 3) E1. Median on Segments (Permutations Edition) (中位数,思维)

    题意:给你一个数组,求有多少子数组的中位数等于\(m\).(若元素个数为偶数,取中间靠左的为中位数). 题解:由中位数的定义我们知道:若数组中\(<m\)的数有\(x\)个,\(>m\)的 ...

  4. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  5. Codeforces Round #523 (Div. 2)

    Codeforces Round #523 (Div. 2) 题目一览表 来源 考察知识点 完成时间 A Coins cf 贪心(签到题) 2018.11.23 B Views Matter cf 思 ...

  6. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  7. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

  8. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  9. Codeforces Round #368 (Div. 2) A. Brain's Photos (水题)

    Brain's Photos 题目链接: http://codeforces.com/contest/707/problem/A Description Small, but very brave, ...

随机推荐

  1. 【python中单链表的实现】——包括初始化、创建、逆序、遍历等

    # coding=utf-8 class mynode(object): def __init__(self, data, nextnode = None): self.data = data sel ...

  2. c#: PointToClient与PointToScreen

    起因: 很早就见过这两个方法,却未曾深入研究,偶尔一用,却纠结于其转换方法,遂写Demo以求验证,记录认知以做备忘. 其为Control类的内置方法,原型为: // // 摘要: // 将指定屏幕点的 ...

  3. win7安装sqlserver2008

    双击启动程序,点击安装

  4. day 17 re模块

    RE模块 import re 对一个大篇幅的字符串,按照你的规则找出想要的字符串 # 单个字符匹配 import re # \w 与 \W #字母数字下划线, 非 # print(re.findall ...

  5. Java IO如何读写文件

    Java把这些不同来源和目标的数据都统一抽象为数据流:Java语言的输入输出功能是十分强大而灵活的:在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上 ...

  6. Java面试基础知识(1)

    1.final, finally, finalize的区别 final:修饰符(关键字)如果一个类被声明为final,没有子类也不能被继承.因此一个类不能既被声明为 abstract的,又被声明为fi ...

  7. python 使用内置方法读取注册表

    #coding:utf-8 import _winreg key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r"键值") #获取该键的 ...

  8. 为什么使用Reazor

    原因:类似于前边写的模板页,自己写了.还需要用replace来替换成自己想要的变量.. 常见的模板引擎:Razor.Nvelocity.Vtemplate. Razor有VS自动提示,而且有助于学习a ...

  9. c# mac地址 和http://xx.xx.xx/ 正则表达式匹配

    Mac  :^([0-9a-fA-F]{2})(([/\s:][0-9a-fA-F]{2}){5})$ C# 书写方式 一下是允许mac中间间隔符是“:”或者“-”两种输入方式 并且我把上边的正则表达 ...

  10. 4A - 排序

    输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数 ...