This is an interactive problem.

You are given a sorted in increasing order singly linked list. You should find the minimum integer in the list which is greater than or equal to x.

More formally, there is a singly liked list built on an array of n elements. Element with index i contains two integers: valuei is the integer value in this element, and nexti that is the index of the next element of the singly linked list (or -1, if the current element is the last). The list is sorted, i.e. if nexti ≠  - 1, then valuenexti > valuei.

You are given the number of elements in the list n, the index of the first element start, and the integer x.

You can make up to 2000 queries of the following two types:

  • ? i (1 ≤ i ≤ n) — ask the values valuei and nexti,
  • ! ans — give the answer for the problem: the minimum integer, greater than or equal to x, or ! -1, if there are no such integers. Your program should terminate after this query.

Write a program that solves this problem.

Input

The first line contains three integers nstartx (1 ≤ n ≤ 50000, 1 ≤ start ≤ n, 0 ≤ x ≤ 109) — the number of elements in the list, the index of the first element and the integer x.

Output

To print the answer for the problem, print ! ans, where ans is the minimum integer in the list greater than or equal to x, or -1, if there is no such integer.

Interaction

To make a query of the first type, print ? i (1 ≤ i ≤ n), where i is the index of element you want to know information about.

After each query of type ? read two integers valuei and nexti (0 ≤ valuei ≤ 109,  - 1 ≤ nexti ≤ nnexti ≠ 0).

It is guaranteed that if nexti ≠  - 1, then valuenexti > valuei, and that the array values give a valid singly linked list with start being the first element.

Note that you can't ask more than 1999 queries of the type ?.

If nexti =  - 1 and valuei =  - 1, then it means that you asked more queries than allowed, or asked an invalid query. Your program should immediately terminate (for example, by calling exit(0)). You will receive "Wrong Answer", it means that you asked more queries than allowed, or asked an invalid query. If you ignore this, you can get other verdicts since your program will continue to read from a closed stream.

Your solution will get "Idleness Limit Exceeded", if you don't print anything or forget to flush the output, including the final answer.

To flush you can use (just after printing a query and line end):

  • fflush(stdout) in C++;
  • System.out.flush() in Java;
  • stdout.flush() in Python;
  • flush(output) in Pascal;
  • For other languages see documentation.

Hacks format

For hacks, use the following format:

In the first line print three integers nstartx (1 ≤ n ≤ 50000, 1 ≤ start ≤ n, 0 ≤ x ≤ 109).

In the next n lines print the description of the elements of the list: in the i-th line print two integers valuei and nexti (0 ≤ valuei ≤ 109,  - 1 ≤ nexti ≤ nnexti ≠ 0).

The printed structure should be a valid singly linked list. In particular, it should be possible to reach all elements from start by following links nexti, and the last element end should have -1 in the nextend.

Example
input
5 3 80
97 -1
58 5
16 2
81 1
79 4
output
? 1
? 2
? 3
? 4
? 5
! 81
Note

You can read more about singly linked list by the following link: https://en.wikipedia.org/wiki/Linked_list#Singly_linked_list

The illustration for the first sample case. Start and finish elements are marked dark.


  题目大意 给定一个元素按升序排序的单向链表,给定开头的下标,查询大于等于x的最小值。每次可以询问一个位置的值和它的下一个元素的下标。询问不得超过1999次。

  这是一道有趣的题目。

  1)如果n不超过1999暴力for整个链表。

  2)否则随机1000个位置查值,然后找到第一个小于x的位置开始往后for。直到链表结束或者找到一个大于等于x的值。

  另外直接srand((unsigned) time (0))会被卡掉,所以但是随机函数就过了。

Code

 /**
* Codeforces
* Problem#844D
* Accepted
* Time: 30ms
* Memory: 500k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean;
typedef pair<int, int> pii; typedef class Random {
public:
unsigned int pre;
unsigned int seed; Random():pre(), seed((unsigned) time (NULL)) { }
Random(int seed):pre(), seed(seed) { } /**
* Generate a random number.
* @return this function will return the random number it gernerated
*/
unsigned int rand() {
// unsigned int ret = (seed * 7361238 + seed % 20037 * 1244 + pre * 12342 + 378211) * (seed + 134543);
// unsigned int ret = (seed * 7361238 + seed % 20037 * 1244 + pre * 12342 + 378211 + time(NULL) * pre) * (seed + 134543);
unsigned int ret;
if(ret & )
ret = (seed * + seed % * + pre * + (time(NULL) * (pre * + seed * + )) + );
else
ret = (seed * + seed % * + pre * + (time(NULL) * (pre * + seed * + )) + );
pre = seed;
seed = ret;
return ret;
} /**
* Generate a random number that between a variable low and a variable high.
* @param low the variable low
* @param high the variable high
* @return if low is not more than high, it will return the random number or it will return 0
*/
unsigned int rand(int low, int high){
if(low > high) return ;
int len = high - low + ;
return rand() % len + low;
}
}Random; Random r;
int n, x, start;
pii *val;
pii ask(int p) {
if(val[p].first != -) return val[p];
pii rt;
printf("? %d\n", p);
fflush(stdout);
scanf("%d%d", &rt.first, &rt.second);
return rt;
} inline void init() {
scanf("%d%d%d", &n, &start, &x);
val = new pii[(n + )];
for(int i = ; i <= n; i++)
val[i].first = -;
} inline void solve1() {
pii data;
for(int i = , p = start; i < n; i++) {
data = ask(p);
if(data.first >= x) {
printf("! %d\n", data.first);
fflush(stdout);
return;
}
p = data.second;
}
puts("! -1");
fflush(stdout);
} const int asktime = ;
boolean *vis;
int pos[asktime + ];
inline void solve2() {
vis = new boolean[(n + )];
memset(vis, false, sizeof(boolean) * (n + ));
vis[start] = true;
for(int i = ; i <= asktime; i++) {
while(vis[(pos[i] = r.rand(, n))]);
vis[pos[i]] = true;
} int s = start;
pii dat = ask(start);
for(int i = ; i <= asktime; i++) {
pii cmp = ask(pos[i]);
if(cmp.first < x && cmp.first > dat.first)
s = pos[i], dat = cmp;
} while(s != -) {
if(dat.first >= x) {
printf("! %d\n", dat.first);
fflush(stdout);
return;
}
s = dat.second;
dat = ask(s);
}
puts("! -1");
fflush(stdout);
} int main() {
init();
if(n <= )
solve1();
else
solve2();
return ;
}

Codeforces 844D Interactive LowerBound - 随机化的更多相关文章

  1. cf 843 B Interactive LowerBound [随机化]

    题面: 传送门 思路: 这是一道交互题 比赛的时候我看到了直接跳过了...... 后来后面的题目卡住了就回来看这道题,发现其实比较水 实际上,从整个序列里面随机选1000个数出来询问,然后从里面找出比 ...

  2. 【AIM Tech Round 4 (Div. 1) B】Interactive LowerBound

    [链接]http://codeforces.com/contest/843/problem/B [题意] 给你一个数组模拟的单链表,放在一个长度为n的数组里面,然后告诉你表头的位置在哪里; 你可以最多 ...

  3. Codeforces 306D - Polygon(随机化+乱搞)

    Codeforces 题目传送门 & 洛谷题目传送门 中考终于结束了--简单写道题恢复下状态罢. 首先这一类题目肯定没法用一般的方法解决,因此考虑用一些奇淫的乱搞做法解决这道题,不难发现,如果 ...

  4. CodeForces 753C Interactive Bulls and Cows (Hard)

    题意:... 析:随机判断就即可,每次把不正确的删除,经过几次后就基本剩不下了. 代码如下: #pragma comment(linker, "/STACK:1024000000,10240 ...

  5. AIM Tech Round 4 (Div. 2)ABCD

    A. Diversity time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  6. 【AIM Tech Round 4 (Div. 2) D Prob】

    ·题目:D. Interactive LowerBound ·英文题,述大意:       有一个长度为n(n<=50000)的单链表,里面的元素是递增的.链表存储在一个数组里面,给出长度n.表 ...

  7. Codeforces Round #192 (Div. 1) C. Graph Reconstruction 随机化

    C. Graph Reconstruction Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/3 ...

  8. Codeforces Round #439 (Div. 2) Problem E (Codeforces 869E) - 暴力 - 随机化 - 二维树状数组 - 差分

    Adieu l'ami. Koyomi is helping Oshino, an acquaintance of his, to take care of an open space around ...

  9. Codeforces Round #358 (Div. 2) E. Alyona and Triangles 随机化

    E. Alyona and Triangles 题目连接: http://codeforces.com/contest/682/problem/E Description You are given ...

随机推荐

  1. struts2实现jQuery的异步交互

    struts2中jQuery的异步交互有两种方式: 1)是利用构造字符串的方式来实现: 使用该方法主要是在服务器端根据前端的请求,返回一个字符串信息,然后前端的jQuery通过解析该字符串信息得到对应 ...

  2. Exception in Spark

    1: Exception in thread "main" org.apache.spark.SparkException: org.apache.spark.streaming. ...

  3. jquer文字闪烁简单实现

    arguments.callee <script type="text/javascript"> (function () { $(".usesend&quo ...

  4. poj2114 寻找树上存在长度为k点对,树上的分治

    寻找树上存在长度为k点对,树上的分治  代码和  这个  差不多 ,改一下判断的就好 #include <iostream> #include <algorithm> #inc ...

  5. C#之Action的实际应用例子

    public class DemoAction{ public Action action; public Action<int> action1; public Action<in ...

  6. 文件、文件夹操作(I)

    遍历一个目录下的所有文件 首先我们获取用户文档目录路径 let manager = FileManager.default let urlForDocument = manager.urls(for: ...

  7. Hive使用pmod函数实现dayofweek函数功能

    dayofweek在hive2.2.0开始支持,低版本的hive原生未提供dayofweek函数(获取一个日期是星期几的方法),所以只有我们自己编写udf函数提供,udf就不说了,在这里给出了一个使用 ...

  8. Docker相关知识整理

    一.进入和退出docker容器 使用docker ps查看容器id docker exec -it containerId /bin/bash //进入容器 Ctrl + P + Q //退出容器 二 ...

  9. go语言,golang学习笔记4 用beego跑一个web应用

    go语言,golang学习笔记4 用beego跑一个web应用 首页 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/ 更新的命令是加个 -u 参数,g ...

  10. 从手机浏览器或者 APP 中跳转到微信并跳转到指定页原理及行业内幕详解

    相信很多朋友遇到过有些网站,可以直接通过一个连接就能让你的手机打开微信且跳转到某个指定的页面,许多程序员很好奇到底是怎么实现的,到处求这种方法的源码,在文本中我会介绍及剖析这种跳转实现的原理. 微信是 ...