洛谷 P6823 「EZEC-4」zrmpaul Loves Array
挂分小技巧
\(m\) 写成 \(n\)。
思路
显然如果找到了最后一个排序操作那么之前的操作可以忽略。
找到最后一个排序操作,如果是 \(1\) 操作就将数组正向赋值,如果是 \(2\) 操作就反向赋值。
用一个标记记录现在的数组是翻转了还是未翻转,如果未翻转则三操作直接翻转 \(x\) 和 \(y\),否则翻转 \(n-x+1\) 和 \(n - y + 1\)。(很好理解,想想看)
然后最后看看当前状态是翻转还是未翻转,如果翻转了就倒序输出,否则正序输出。
代码
/*
Time: 18/09/20 20:15
Author: Loceaner
Description:
Debug: m写成n
*/
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int A = 1e6 + 11;
const int B = 1e6 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar();
int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int n, m, a[A], last, opt;
struct node { int opt, x, y; } cz[A];
int main() {
n = read(), m = read();
for (int i = 1; i <= m; i++) {
int lx = read();
if (lx == 1 || lx == 2) last = i, opt = lx;
if (lx == 3) {
int x = read(), y = read();
cz[i].x = x, cz[i].y = y;
}
cz[i].opt = lx;
}
if (opt == 2) for (int i = 1; i <= n; i++) a[i] = n - i + 1;
else for (int i = 1; i <= n; i++) a[i] = i;
int flag = 0;
for (int i = last + 1; i <= m; i++) {
if (cz[i].opt == 3) {
if (!flag) swap(a[cz[i].x], a[cz[i].y]);
else swap(a[n - cz[i].x + 1], a[n - cz[i].y + 1]);
}
else flag ^= 1;
}
if (!flag) for (int i = 1; i <= n; i++) cout << a[i] << " ";
else for (int i = n; i >= 1; i--) cout << a[i] << " ";
return 0;
}
转载不必联系作者,但请声明出处