ARC110F Esoswap

ARC110F Esoswap

由于 0n10\sim n-1 的特殊性,每次固定询问一个位置,询问 nn 次一定会得到 00,且每次在这个位置上的数不会重复(00 除外)。

于是考虑倒序将数固定,正序会出现问题。

然后把倒序排列转为正序排列。

具体地,先把 11 交换到位置 n1n-1,然后将在 00 位置上的数与 11 交换,然后 11 一直往右移动到 n2n-2,重复上面操作即可。

操作数 O(n2)\mathcal O(n ^2)

#include<cstdio>

//using namespace std;

typedef long long ll;

#define ha putchar(' ')
#define he putchar('\n')

inline int read() {
	int x = 0;
	char c = getchar();
	while (c < '0' || c > '9')
		c = getchar();
	while (c >= '0' && c <= '9')
		x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	return x;
}

inline void write(int x) {
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + 48);
}

void swap(int &a, int &b)
{
	int t = a;
	a = b, b = t;
}

const int _ = 107;

int n, a[_], id[_], as[200010];

void sol(int x) {
	as[++as[0]] = x;
	swap(id[a[x]], id[a[(x + a[x]) % n]]);
	swap(a[x], a[(x + a[x]) % n]);
}

signed main() {
	n = read();
	for (int i = 0; i < n; ++i) a[i] = read(), id[a[i]] = i;
	while (a[n - 1] != 0) sol(n - 1);
	for (int i = n - 1; i >= 0; --i)
		while (a[i] != n - 1 - i) sol(i);
	sol(id[1]);
	for(int i = n - 1; i > 1; --i)
	{
		sol(id[i]);
		while(a[i - 1] != 1) sol(id[1]);
	}
	for (int i = 0; i <= as[0]; ++i) write(as[i]), he;
	return 0;
}
posted @ 2022-07-18 18:12  蒟蒻orz  阅读(2)  评论(0编辑  收藏  举报  来源