题解:CF2059E2 Stop Gaming (Hard Version)
为什么没有人提到线性做法?
把输入矩阵拍平成序列,序列被划分为
显然
但注意到不是所有匹配
因此序列合法当且仅当所有
考虑贪心,从前往后贪心匹配,记录
考虑如何输出方案,由于已经确定了哪些数是位于子序列中,
由于
#include<bits/stdc++.h>
using ll = long long; using ull = unsigned long long; using uint = unsigned int;
#define ld std::cin
#define jyt std::cout
#define cmd std::cerr
#define REQ(i, l, r) for (int i = l; i < r; ++i)
#define REP(i, l, r) for (int i = l; i <= r; ++i)
#define PER(i, l, r) for (int i = l; i >= r; --i)
const int MAXL = 1 << 20; char buf[MAXL], *buf1 = buf, *buf2 = buf;
#define gc() (buf1 == buf2 && (buf2 = (buf1 = buf) + fread(buf, 1, MAXL, stdin), buf1 == buf2) ? EOF : *buf1++)
inline ll ldr() {
ll x = 0; bool f = 0; char ch = gc();
while (ch < '0' || '9' < ch) f = (ch == '-'), ch = gc();
while ('0' <= ch && ch <= '9') x = x * 10 + (ll)(ch - '0'), ch = gc();
return (f ? -x : +x);
}
inline int ldc() { char ch = gc(); while (ch < 'a' || 'z' < ch) ch = gc(); return ch - 'a'; }
inline int ldn() { char ch = gc(); while (ch < '0' || '9' < ch) ch = gc(); return ch - '0'; }
#define mset(a, v, n) memset((a), (v), sizeof((a)[0]) * (n))
std::mt19937_64 R64(std::chrono::steady_clock::now().time_since_epoch().count());
const int N = 3e5 + 3;
int H, W, n, a[N], b[N];
bool mark[N]; std::list<std::pair<int, int> > S;
inline signed Create() {
H = ldr(), W = ldr(), n = H * W;
REP(i, 1, n) a[i] = ldr();
REP(i, 1, n) b[i] = ldr();
int lim = 1, pt = 1;
REP(i, 1, n) {
if (a[pt] == b[i]) { ++pt; continue; }
int _ = std::max(0, (i - 1) % W + 1 - lim);
REQ(k, i - _, i) mark[k] = 1;
pt -= _, lim += _, mark[i] = 1, ++lim;
}
jyt << n - (pt - 1) << '\n';
auto it = S.begin(); int rk = 0;
REP(i, 1, n) if (mark[i]) {
int _ = (i - 1) % W, f = (i - 1) / W + 1;
if (rk > _) it = S.begin(), rk = 0;
while (rk < _) ++it, ++rk;
it = S.insert(it, std::make_pair(f, b[i]));
}
std::reverse(S.begin(), S.end());
for (auto node : S) jyt << node.first << ' ' << node.second << '\n';
return 0;
}
inline void FlyWheel() { S.clear(); REP(i, 1, n) mark[i] = 0; }
signed main() {
std::ios::sync_with_stdio(false), ld.tie(0), jyt.tie(0);
int TEST = ldr();
while (TEST--) Create(), FlyWheel();
return 0;
}