Take a Guess
题意
给一个未知的长n的数字序列,允许最大2n次的取与操作或取或操作,询问第k大的数字
思路
a + b = a & b + a | b
有这个就可以先把前三个数处理出来,其余的也都出来了,注意位运算顺序。
(如何构想出来的还在思考)
AC代码
基本上参考t神的···真的思路清晰又简洁
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define endl '\n'
//#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 10 + 1e5, mod = 1e9 + 7;
void solve()
{
int n, k;
cin >> n >> k;
// 实现两个and or 操作
auto And = [&](int i, int j)
{
cout << "and " << i + 1 << ' ' << j + 1 << endl;
ll ans;
cin >> ans;
return ans;
};
auto Or = [&](int i, int j)
{
cout << "or " << i + 1 << ' ' << j + 1 << endl;
ll ans;
cin >> ans;
return ans;
};
vector<ll> a(n);
{// 构造出前3个数
ll s01 = And(0, 1) + Or(0, 1);
ll s02 = And(0, 2) + Or(0, 2);
ll s12 = And(1, 2) + Or(1, 2);
a[0] = s01 + s02 - s12 >> 1;
a[1] = s12 + s01 - s02 >> 1;
a[2] = s02 + s12 - s01 >> 1;
}
for (int i = 3; i < n; i++)
{// 处理后面的数
ll s0i = And(0, i) + Or(0, i);
a[i] = s0i - a[0];
}
sort(a.begin(), a.end());
cout << "finish " << a[k - 1] << endl;
}
signed main()
{
ios::sync_with_stdio();
cin.tie(), cout.tie();
solve();
return 0;
}