题解:AT_joisc2016_b 神経衰弱
提供一个思路比较简单的做法。
考虑如果我们能找出
考虑怎么找出这个位置。
考虑这样一个事实:我们随便选一个位置
据此我们可以划分出
于是我们可以不断划分,直到剩下两个位置,这两个位置就是
随机选择一个位置开始划分,每次期望可以把候选集缩小一半。于是总询问次数是
显然我们根本没有必要重新扫一遍。回顾我们的过程,那些
这样做总询问次数就是
vector <int> p;
int maxid;
mt19937 rnd(time(0));
vector <int> bol[55];
bool vis[110];
vector <int> col[55];
void Solve(int tc, int n){
fr1(i,0,2*n-1) p.pb(i);
while(p.size()>2){
int id=p[rnd()%p.size()];
for(auto i:p){
if(id==i) continue;
int val=Flip(i,id);
bol[val].pb(i);
}
p.clear();
fr1(i,0,n-1){
if(bol[i].size()==2){
for(auto j:bol[i]) vis[j]=1;
col[i]=bol[i];
continue;
}
for(auto j:bol[i]) p.pb(j);
}
p.pb(id);
fr1(i,0,n-1) bol[i].clear();
}
maxid=p[0];
fr1(i,0,2*n-1){
if(vis[i]) continue;
if(maxid!=i) col[Flip(i,maxid)].pb(i);
}
fr1(i,0,n-1){
if(col[i].size()==2) Answer(col[i][0],col[i][1],i);
else Answer(col[i][0],maxid,i);
}
}