#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include "permutation.h"
#pragma GCC optimize("-O3")
#pragma GCC optimize("unroll-loops")
#define fi first
#define se second
#define ll long long
#define ld long double
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mpp make_pair
#define ve vector
using namespace std;
using namespace __gnu_pbds;
template<class T> using oset = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
const ll inf = 1e18; const int iinf = 1e9;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
mt19937_64 rng(chrono::stady_clock::now().time_since_epoch().count());
template <typename T> inline bool chmin(T& a, T b) { return (a > b ? a = b, 1 : 0); }
template <typename T> inline bool chmax(T& a, T b) { return (a < b ? a = b, 1 : 0); }
const int N = 300;
int nn;
int p[N];
int res[N], df[N], used[N];
inline void rec(int pos) {
if (pos == nn - 1) {
int dif = df[0];
if (abs(p[0] - p[nn - 1]) != dif) {
return;
}
answer(p);
}
int cur = p[pos];
int Dif = df[(pos + 1) % nn];
int sgn = (rng() % 2 == 1 ? 1 : -1);
int dif = Dif * sgn;
if (cur + dif >= 1 && cur + dif <= nn && !used[cur + dif]) {
used[cur + dif] = 1;
p[pos + 1] = cur + dif;
rec(pos + 1);
p[pos + 1] = -1;
used[cur + dif] = 0;
}
sgn *= -1;
dif = Dif * sgn;
if (cur + dif >= 1 && cur + dif <= nn && !used[cur + dif]) {
used[cur + dif] = 1;
p[pos + 1] = cur + dif;
rec(pos + 1);
p[pos + 1] = -1;
used[cur + dif] = 0;
}
}
void solve(int n) {
if (n == 1) {
answer(ve<int>{1});
}
nn = n;
for (int i = 0; i < n; ++i) {
ve<int> p(n);
for (int c = 0; c < n; ++c) {
p[c] = ((i + c) % n + 1);
}
res[i] = query(p);
}
int s = accumulate(res, res + n, 0);
for (int i = 0; i < n; ++i) {
df[i] = (s / (n - 1)) - res[i];
}
ve<int> F(n);
iota(all(F), 1);
shuffle(all(F), rng);
for (const auto &i : F) {
int dif = df[1];
if ((i + dif >= 1 && i + dif <= n) || (i - dif >= 1 && i - dif <= n)) {
p[0] = i;
used[i] = 1;
rec(0);
used[i] = 0;
p[0] = -1;
}
}
}
#ifdef LOCAL
namespace A {
int N;
const int MAX_N = 1000;
int P[1 + MAX_N];
int queries = 0;
void readInput() {
//printf("The permutation you have to guess is:\n");
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
scanf("%d", &P[i]);
//printf("%d ", P[i]);
}
//printf("\n");
}
int query(int V[]) {
queries++;
printf("query(");
for (int i = 0; i < N - 1; i++) {
printf("%d, ", V[i]);
}
printf("%d) = ", V[N - 1]);
int freq[1 + N];
for (int i = 0; i <= N; i++) {
freq[i] = 0;
}
for (int i = 0; i < N; i++) {
freq[V[i]]++;
}
for (int i = 1; i <= N; i++) {
assert(freq[i] == 1);
}
int answer = 0;
for (int i = 0; i + 1 < N; i++) {
answer += abs(P[V[i + 1]] - P[V[i]]);
}
printf("%d\n", answer);
fflush(stdout);
return answer;
}
void answer(int V[]) {
bool ok = true;
ve<int> p(N);
iota(all(p), 1);
do {
int ans_jury = 0;
for (int i = 0; i < N - 1; ++i) ans_jury += abs(P[p[i]] - P[p[i + 1]]);
int ans_mine = 0;
for (int i = 0; i < N - 1; ++i) ans_mine += abs(V[p[i] - 1] - V[p[i + 1] - 1]);
ok &= (ans_jury == ans_mine);
if (!ok) break;
} while (next_permutation(all(p)));
if (ok) {
printf("Correct! with N = %d, Q = %d\n", N, queries);
} else {
printf("Wrong answer!\n");
}
exit(0);
}
}
int query(int p[]) {
return A::query(p);
}
void answer(int ans[]) {
A::answer(ans);
}
int query(std::vector<int> v) {
int array[A::N];
for (int i = 0; i < A::N; i++) {
array[i] = v[i];
}
return query(array);
}
void answer(std::vector<int> v) {
int array[A::N];
for (int i = 0; i < A::N; i++) {
array[i] = v[i];
}
answer(array);
}
int main(int argc, char **argv) {
A::readInput();
solve(A::N);
return 0;
}
#endif
Compilation message
permutation.cpp:22:24: error: 'std::chrono::stady_clock' has not been declared
22 | mt19937_64 rng(chrono::stady_clock::now().time_since_epoch().count());
| ^~~~~~~~~~~
permutation.cpp: In function 'void rec(int)':
permutation.cpp:39:10: error: could not convert '(int*)(& p)' from 'int*' to 'std::vector<int>'
39 | answer(p);
| ^
| |
| int*
stub.cpp: In function 'int query(int*)':
stub.cpp:15:9: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
15 | fscanf(stdin, "%d", &x);
| ~~~~~~^~~~~~~~~~~~~~~~~
stub.cpp: In function 'int main(int, char**)':
stub.cpp:48:9: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
48 | fscanf(stdin, "%d", &N);
| ~~~~~~^~~~~~~~~~~~~~~~~