CFgym:Ex Machina(交互 & 线段树区间最值)

M. Ex Machina
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Special agent Adam is hacking a calculator of a member of the secret mason organization of Illuminati in order to get access to the information about its leaders. He has already found out that the organization consists of n members, each of which has its own unique index number from 1 to n. Moreover, every member of the organization has a level which is also an integer from 1 to n, and all levels are pairwise distinct. Every Illuminati can give commands to Illuminati of lower levels, but has to obey the Illuminati of higher levels. Adam thinks that the information leak about the Illuminati with the highest level n can discredit him, so he is interested in the Illuminati with the level n - 1, who obeys only the Illuminati with the highest level.

It was quite hard to get access to the secret Illuminati network, so the only request Adam can make is to compare levels of two Illuminati with the given index numbers. Making such request, he gets a response which tells if the level of the first Illuminati is higher, lower or equal to the level of the second Illuminati. The number of requests is limited, but as the Illuminati's calculator highly respects powers of two, Adam can safely make  requests before his presence in the network will be detected.

Interaction

It's an interactive problem. Here, your program must communicate with the jury's program using standard input and output.

At the beginning, the input contains a line with a single integer n (2 ≤ n ≤ 1000) — the number of Illuminati.

After that your program can make requests to compare two Illuminati. To do that, in a separate line output a character «?» and then two integers, separated by spaces — the index numbers of Illuminati to compare. As a response, a separate line will contain a character «<» if the first Illuminati has the level lower than the second one, a character «>» if the first Illuminati has the level higher than the second one, or a character «=» if the given Illuminati have the same level. You can make no more than  such requests.

When you will know the answer, output a character «!» and a single integer, separated by a space — the index number of Illuminati with the level n - 1.

Example
input
5
>
>
>
>
>
<
>
output
? 1 2
? 1 3
? 1 4
? 1 5
? 2 3
? 2 4
? 4 5
! 4
Note

Notice that after printing each message your program must flush the output buffer so that the information you have printed reached the jury's program. For example, the calls «fflush(stdout)» or «cout.flush()» in C++, «System.out.flush()» in Java, «Console.Out.Flush()» in C#, «flush(output)» in Pascal, «sys.stdout.flush()» in Python do that.

题意:有N个人,线性的上司与下属关系,最多n+24次询问两个人的上下级关系,输出排名第二的boss。

思路:先用线段树得出大boss所在区间,然后再跑一遍线段树,将所有可能的排第二的候选人存下来,再在候选人中选出其中的boss即为排第二的boss。

# include <iostream>
# include <cstdio>
# define lson l, m, id<<1
# define rson m+1, r, id<<1|1
using namespace std;
const int maxn = 1100;
int cnt=0, n, root[maxn<<2], second[maxn], nex[maxn<<2];
char s[5];

int ask(int l, int r)
{
    printf("? %d %d\n",l, r);
    fflush(stdout);
    scanf("%s",s);
    if(s[0] == '>')
        return 1;
    return 0;
}

void query(int id)
{
    int l = root[id<<1], r = root[id<<1|1];
    if(ask(l, r))
    {
        root[id] = l;
        nex[id] = 1;
    }
    else
    {
        root[id] = r;
        nex[id] = 2;
    }
}

void build(int l, int r, int id)
{
    if(l == r)
    {
        root[id] = l;
        return;
    }
    int m = l+r>>1;
    build(lson);
    build(rson);
    query(id);
}

void solve(int l, int r, int id)
{
    if(l == r) return;
    int m = l+r>>1;
    if(nex[id] == 1)
    {
        second[cnt++] = root[id<<1|1];
        solve(lson);
    }
    else
    {
        second[cnt++] = root[id<<1];
        solve(rson);
    }
}

int main()
{
    scanf("%d",&n);
    build(1, n, 1);
    solve(1, n, 1);
    int ans = second[0];
    for(int i=1; i<cnt; ++i)
        if(ask(second[i], ans))
            ans = second[i];
    printf("! %d\n",ans);
    fflush(stdout);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值