首页 > 其他分享 >CF1698 F

CF1698 F

时间:2024-07-20 12:10:10浏览次数:12  
标签:... CF1698 return void write template define

CF1698 F

不错的题目。

考虑必要条件,也就是不变量,发现操作不改变相邻二元组集合,且不能改变 \(a_1,a_n\)。那么必要条件就是 \(a,b\) 相邻二元组集合相等和 \(a_1=b_1,a_n=b_n\)。

通过构造证明充分性。

对于此类从 \(a\) 操作到 \(b\) 的问题,且操作可逆,不妨考虑中间状态 \(c\),考虑如何操作使得 \(a\rightarrow c,b\rightarrow c\)。

设目前操作前 \(i\) 为 \(a,b\) 对应相等,\(a_i=x,a_{i+1}=y,b_{i+1}=z\),首先分别考察 \(a_{i\dots n}\) 中有无 \(zx\) 和 \(b_{i\dots n}\) 中有无 \(yx\),有的话直接换。

否则猜测必然存在 \(a\) 使得 \(ax\) 在 \(a,b\) 同时存在,考察在 \(a_{i\dots n}\) 和 \(b_{i\dots n}\),对于任意字符 \(p\),形如 \(px\) 和 \(xp\) 的个数,由于目前存在 \(xy\) 和 \(xz\),那么它们在 \(a,b\) 中相差不超过 \(2\)。

目前已经出现 \(4\) 个 \(xp\) 的形式,且 \((p,x)\) 在 \(a,b\) 中出现次数相同,要使得 \(px\) 和 \(xp\) 在 \(a,b\) 中相差不超过 \(2\),那么必然存在一组对应的 \(px\) 存在,那么总操作次数不超过 \(2n\),每次暴力查找,复杂度 \(\mathcal{O}(n^2)\)。

或者考虑连边 \((a_i,a_{i+1})\),用欧拉回路做即可,实现差不多,都很简单。

类似方法:CF1458 D

#include <bits/stdc++.h>
#define file_in(x) (freopen(#x".in", "r", stdin))
#define file_out(x) (freopen(#x".out", "w", stdout))
#define ll long long
#define vi vector
#define pb push_back
#define db double
#define pr pair <int, int>
#define mk make_pair
#define fi first
#define se second
#define lb(x) (x & (-x))

using namespace std;

char _c; bool _f; template <class T> void IN(T &x) {
  _f = x = 0; while (_c = getchar(), !isdigit(_c)) {if (_c == '-') _f = 1;}
  while (isdigit(_c)) {x = x * 10 + _c - '0', _c = getchar();} if (_f) x = -x;
}

template <class T> void _write(T x) {
  if (x < 0) return putchar('-'), _write(-x), void();
  if (x > 9) _write(x / 10);
  putchar('0' + x % 10);
}
template <class T> void write(T x) {_write(x), putchar('\n');}
template <class T> void write_s(T x) {_write(x), putchar(' ');}
template <class first, class... rest> void write(first fir, rest... res) {
  write_s(fir), write(res...);
}

#define debug(...) (_debug(#__VA_ARGS__, __VA_ARGS__))
template <class T> void _debug(const char *format, T x) {
  cerr << format << " = " << x << endl;
}
template <class first, class... rest>
void _debug(const char *format, first fir, rest... res) {
  while (*format != ',') cerr << *format++;
  cerr << " = " << fir << ',', _debug(format + 1, res...);
}

bool START;

const int N = 505;

int t_c, n, a[N], b[N], p[N];
vi <pr> va, vb;

bool END;

bool chk() {
  if (a[1] != b[1] || a[n] != b[n]) return 1;
  for (int i = 0; i < n - 1; ++i) if (va[i] != vb[i]) return 1;
  return 0;
}

void opa(int l, int r) {
  va.pb(mk(l, r));
  for (int i = 1; 2 * i <= r - l + 1; ++i) swap(a[l + i - 1], a[r - i + 1]);
}

void opb(int l, int r) {
  vb.pb(mk(l, r));
  for (int i = 1; 2 * i <= r - l + 1; ++i) swap(b[l + i - 1], b[r - i + 1]);
}

signed main() {
  IN(t_c);
  while (t_c--) {
    IN(n), va.clear(), vb.clear();
    for (int i = 1; i <= n; ++i) IN(a[i]);
    for (int i = 1; i <= n; ++i) IN(b[i]);
    for (int i = 1; i < n; ++i) {
      va.pb(mk(min(a[i], a[i + 1]), max(a[i], a[i + 1])));
      vb.pb(mk(min(b[i], b[i + 1]), max(b[i], b[i + 1])));
    }
    sort(va.begin(), va.end()), sort(vb.begin(), vb.end());
    if (chk()) {puts("NO"); continue;}
    va.clear(), vb.clear(), puts("YES");
    for (int i = 1; i < n; ++i) {
      int x = a[i], y = a[i + 1], z = b[i + 1];
      bool fl = 0;
      for (int j = i + 1; j < n; ++j) if (a[j] == z && a[j + 1] == x) {opa(i, j + 1), fl = 1; break;}
      if (fl) continue;
      for (int j = i + 1; j < n; ++j) if (b[j] == y && b[j + 1] == x) {opb(i, j + 1), fl = 1; break;}
      if (fl) continue;
      for (int j = 0; j <= n; ++j) p[j] = 0;
      for (int j = i + 1; j < n; ++j) if (a[j + 1] == x) p[a[j]] = j + 1;
      for (int j = i + 1; j < n; ++j) if (b[j + 1] == x && p[b[j]]) {opa(i, p[b[j]]), opb(i, j + 1); break;}
    }
    write((int)va.size() + vb.size());
    for (auto x : va) write(x.fi, x.se);
    reverse(vb.begin(), vb.end());
    for (auto x : vb) write(x.fi, x.se);
  }
  return 0;
}

标签:...,CF1698,return,void,write,template,define
From: https://www.cnblogs.com/Tagaki-san/p/18312929

相关文章

  • 【CF1698C】3SUM Closure
    题目大意:判断一个数组是否满足其中任意三个元素之和均为数组的元素如果一个元素出现的次数大于三,那么我们将这个元素的数量减到三,答案不会变。另外,我们发现,如果数组至少中有三个正数,或者至少有三个负数,那么答案一定为NO。如果上面的条件不满足,那么现在这个数组里的元素最多只......
  • CF1698F题解
    考虑一个函数\(f(a)\),它的返回值是一个二维数组\(b\),接受值是一个数组\(a\)。对于所有\(i=1\ton-1\)的\(i\),把\(b_{a_i}{a_{i+1}}++\),然后返回\(b\)。\(f(a)!=f(b)\)且\(a_1=b_1,a_n=b_n\)是无解的充要条件,因为显然对于数组的每次翻转操作它的\(f\)返回值都不会变。\(f(a)!=f(b......
  • CF1698G Long Binary String
    题面传送门以前一直以为BSGS要有逆才能做/xia首先观察一下,全序列第一个\(1\)显然是消不掉的,因为没有比它更前面的异或了,同理最后面的也是消不掉的。因此我们已经知道了......