思路:每个位置上出现的数字最终一定成为一个环,且若前一次查询中第i位置上的元素为 x x x,则后一次查询时第i位置上的元素为 P x P_x Px.那么我们可以利用这个性质在每个环中查找该环上的所有数,最多需要n+c次查询,c是一个小常数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int ask(int x)
{
cout << "? " << x+1 << endl;
int t;
cin >> t;
return t - 1;
}
void solve() {
int n;
cin >> n;
vector<int> ans(n, -1);
for (int i = 0;i < n;i++)
{
if (ans[i] == -1)
{
int end = ask(i);
int x = ask(i);
vector<int> cycle;
cycle.push_back(x);
while (x != end)
{
x = ask(i);
cycle.push_back(x);
}
for (int j = 0;j < cycle.size();j++)
{
ans[cycle[j]] = cycle[(j + 1) % cycle.size()];
}
}
}
cout << "!";
for (auto x : ans)cout << " " <<x+1;
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}