洛谷 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;  
}
原文地址:https://www.cnblogs.com/loceaner/p/13693681.html