#include "choreography.h"
#include <vector>
#include <algorithm>
using namespace std;
static int total_dancers;
static int permutations[2][100005]; // [0]: dancer->initial_pos, [1]: initial_pos->dancer
static int active_perm = 0; // Toggles on move_around()
// add[0/1] = offsets applied AFTER the current inversion state
// rem[0/1] = offsets applied BEFORE the current inversion state
static int add[2] = {0, 0};
static int rem[2] = {0, 0};
void init(int n, vector<int> P) {
total_dancers = n;
for (int i = 0; i < n; ++i) {
permutations[0][i] = P[i];
permutations[1][P[i]] = i;
}
active_perm = 1; // Starting state matches your 'cur = 1'
}
void move_right(int K) {
for (int i = 0; i < 2; ++i) {
add[i] = (add[i] + K) % total_dancers;
}
}
void move_left(int K) {
move_right(total_dancers - K);
}
void swap_places() {
for (int i = 0; i < 2; ++i) {
// If the current position of this group is even, move +1, else move -1
if ((add[i] % 2 == 0 && i == 0) || (add[i] % 2 != 0 && i == 1)) {
add[i] = (add[i] + 1) % total_dancers;
} else {
add[i] = (add[i] - 1 + total_dancers) % total_dancers;
}
}
}
void move_around() {
active_perm ^= 1;
for (int i = 0; i < 2; ++i) {
swap(add[i], rem[i]);
}
}
int get_position(int D) {
// 1. Determine parity group and remove 'pre' offsets
// This logic must match: D -= rem[(D - rem[0]) & 1]
int group_index = (D - rem[0] + total_dancers) % 2;
D = (D - rem[group_index] + total_dancers) % total_dancers;
// 2. Initial Permutation Lookup
D = permutations[active_perm][D];
// 3. Apply 'post' offsets
D = (D + add[D % 2]) % total_dancers;
return D;
}