CodeForces - 1698D 交互题

CodeForces - 1698D   交互题

This is an interactive problem.

Initially, there is an array �=[1,2,…,�]a=[1,2,…,n], where �n is an odd positive integer. The jury has selected �−122n−1​ disjoint pairs of elements, and then the elements in those pairs are swapped. For example, if �=[1,2,3,4,5]a=[1,2,3,4,5], and the pairs 1↔41↔4 and 3↔53↔5 are swapped, then the resulting array is [4,2,5,1,3][4,2,5,1,3].

As a result of these swaps, exactly one element will not change position. You need to find this element.

To do this, you can ask several queries. In each query, you can pick two integers �l and �r (1≤�≤�≤�1≤l≤r≤n). In return, you will be given the elements of the subarray [��,��+1,…,��][al​,al+1​,…,ar​] sorted in increasing order.

Find the element which did not change position. You can make at most 1515 queries.

The array �a is fixed before the interaction and does not change after your queries.

Recall that an array �b is a subarray of the array �a if �b can be obtained from �a by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end.

Input

Each test contains multiple test cases. The first line contains an integer �t (1≤�≤5001≤t≤500) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer �n (3≤�<1043≤n<104; �n is odd) — the length of the array �a.

After reading the first line of each test case, you should begin the interaction.

It is guaranteed that the sum of �n over all test cases does not exceed 104104.

Interaction

For each test case, begin the interaction by reading the integer �n.

To make a query, output "?��?lr" (1≤�≤�≤�1≤l≤r≤n) without quotes. Afterwards, you should read in �−�+1r−l+1 integers — the integers ��,��+1,…,��al​,al+1​,…,ar​, in increasing order. You can make at most 1515 such queries in a single test case.

If you receive the integer −1−1 instead of an answer or the integer �n, it means your program has made an invalid query, has exceed the limit of queries, or has given incorrect answer on the previous test case. Your program must terminate immediately to receive a Wrong Answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

When you are ready to give the final answer, output "!�!x" (1≤�≤�1≤x≤n) without quotes — the element that did not change position. Giving this answer does not count towards the limit of 1515 queries. Afterwards, your program must continue to solve the remaining test cases, or exit if all test cases have been solved.

After printing a query do not forget to output end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

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

Hacks

To make a hack, use the following format. The first line must contain an integer �t (1≤�≤5001≤t≤500) — the number of test cases. The description of the test cases follows.

The first line of each test case must contain an integer �n (3≤�<1043≤n<104; �n is odd) — the length of the array �a.

The second line of each test case must contain �n space-separated integers �1,�2,…,��a1​,a2​,…,an​ (1≤��≤�1≤ai​≤n) — the elements of �a. The array �a should be the result of �−122n−1​ disjoint swaps on the array [1,2,…,�][1,2,…,n].

#include<bits/stdc++.h>
using namespace std;
#define Acode ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
//#define endl '\n'
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-6;
int x;
int l, r;
bool check(int mid)
{
	int cnt = 0;
	cout << "? " << l << " " << mid << endl;
	for (int i = l; i <= mid; i++)
	{
		int x;
		cin >> x;
		if (x <= mid && x >= l) cnt++;
	}
	if (cnt & 1) return true;
	else return false;
}

int main()
{
	Acode;
	int t;
	cin >> t;
	while (t--)
	{
		cin >> x;
		l = 1; r = x;
		while (l <= r)
		{
			int mid = l + r >> 1;
			if (check(mid)) r = mid - 1;
			else l = mid + 1;
		}
		cout << "! " << l << endl;
	}

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值