You can not have it both ways

Title Description

Interaction. Each time a query can be arranged, and returns the answer to this arrangement the same number of arrangement positions, are arranged to obtain the answer.

data range

$ N \ 5 \ times 10 ^ 3; queries \ 5 \ times 10 ^ 4 $

answer

Consider first find a wrong row, then the answer will be shaped like a ring in the form of a number of substitutions. Therefore, our goal is $ \ frac {(n-1) \ times n} {2} $ sides, the article is selected $ $ n-side effective.

Consider the nature of the effective side, i.e. the exchange side effective numerical endpoint interrogation result will increase. So for each edge $ (i, j) $, considered in the $ (i + j) \% n $ packet, two on each end of each side differ from each other, we can use a method similar to the partition which side is determined to be effective, the final orientation can be.

Code

#include "game.h"
using namespace std;
const int N=5005;
struct O{int x,y;};
vector<O>p[N],h;
vector<int>f[N],a;
int g[N<<2],S[N],cnt,lst,d[N];
bool vis[N];
bool J(int u){return d[u]<2;}
void add(int u,int v){d[u]++;f[u].push_back(v);}
void find(int k,int i,int l,int r){
    if (l==r){
        add(p[i][l].x,p[i][l].y);
        add(p[i][l].y,p[i][l].x);
        return;
    }
    int Ls=(k<<1),Rs=(Ls|1),mid=(l+r)>>1;
    for (int j=l;j<=mid;j++)
        swap(a[p[i][j].x],a[p[i][j].y]);
    g[Ls]=count(a);g[Rs]=g[k]-g[Ls];
    for (int j=l;j<=mid;j++)
        swap(a[p[i][j].x],a[p[i][j].y]);
    if (g[Ls]) find(Ls,i,l,mid);
    if (g[Rs]) find(Rs,i,mid+1,r);
}
void dfs(int u){
    vis[u]=1;S[++cnt]=u;
    int z=f[u].size();
    for (int i=0;i<z;i++)
        if (!vis[f[u][i]]){
            swap(a[u],a[f[u][i]]);
            dfs(f[u][i]);
        }
}
vector<int>guess(int n,int limit){
    srand(233);a.resize(n);
    for (int i=1;i<=n;i++) a[i-1]=i;
    if (n==1) return a;
    while(count(a))
        random_shuffle(a.begin(),a.end());
    for (int i=0;i<n;i++)
        for (int j=i+1;j<n;j++)
            p[(i+j)%n].push_back((O){i,j});
    for (int z,i=0;i<n;i++){
        z=p[i].size();if (!z) continue;h.clear();
        for (int j=0;j<z;j++)
            if (J(p[i][j].x) && J(p[i][j].y))
                h.push_back(p[i][j]);
        p[i]=h;z=p[i].size();if (!z) continue;
        for (int j=0;j<z;j++)
            swap(a[p[i][j].x],a[p[i][j].y]);
        g[1]=count(a);
        for (int j=0;j<z;j++)
            swap(a[p[i][j].x],a[p[i][j].y]);
        if (g[1]) find(1,i,0,z-1);
    }
    for (int i=0,v;i<n;i++)
        if (!vis[i]){
            cnt=0;dfs(i);v=count(a);
            if (v==lst){
                for (int j=cnt-1;j;j--)
                    swap(a[S[j+1]],a[S[j]]);
                swap(a[S[1]],a[S[cnt]]);
                for (int j=cnt-1;j>1;j--)
                    swap(a[S[j+1]],a[S[j]]);
            }
            lst+=cnt;
        }
    return a;
}

 

Guess you like

Origin www.cnblogs.com/xjqxjq/p/12003486.html