题解:CF2061G Kevin and Teams
[CF2061G] Kevin and Teams
考虑一种构造:将
考虑询问方案:维护一条同色链,令链的末尾的点为
#include<bits/stdc++.h>
#define ll long long
#define pn putchar('\n')
#define mset(a,x) memset(a,x,sizeof a)
#define mcpy(a,b) memcpy(a,b,sizeof a)
#define all(a) a.begin(),a.end()
#define fls() fflush(stdout)
using namespace std;
int re()
{
int x=0;
bool t=1;
char ch=getchar();
while(ch>'9'||ch<'0')
t=ch=='-'?0:t,ch=getchar();
while(ch>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return t?x:-x;
}
int n,m;
stack<int>st;
vector<pair<int,int>>ans[2];
void solve()
{
n=re();m=(n+1)/3;
printf("%d\n",m);
fls();
bool cl=0;
while(st.size())
st.pop();
ans[0].clear();
ans[1].clear();
for(int i=1;i<=n;i++)
{
if(!st.size())
st.push(i);
else
{
int t=st.top();
printf("? %d %d\n",t,i);
fls();
bool ret=re();
if(st.size()==1)
cl=ret;
if(cl!=ret)
{
ans[ret].push_back({t,i});
st.pop();
int t2=st.top();
ans[cl].push_back({t2,t});
st.pop();
}
else
st.push(i);
}
}
while(st.size()>=2)
{
int t=st.top();
st.pop();
int t2=st.top();
st.pop();
ans[cl].push_back({t,t2});
}
if(ans[0].size()<m)
swap(ans[0],ans[1]);
ans[0].resize(m);
printf("! ");
for(auto [u,v]:ans[0])
printf("%d %d ",u,v);
pn;
fls();
}
signed main()
{
int T=re();
while(T--)
solve();
return 0;
}