题解:P11244 吻秋
upd:出题人卡了时限使我 cin 过不了了,重修一下。
大家好啊,我是一个蒟蒻,场上因为不会 STL 调试非常久,然后成功被创似了。
因为我是无勾蒟蒻,所以我来讲一个非常非常无脑的做法。
首先丢个结论:对于交换
证明:
结论 A:交换
结论 B:对
然后,对于一对
在每次操作后,我们都对
无效操作显然是
-
没有贡献。
-
结果仅仅是交换了两个数组。我们不妨用
f_x 表示第x 个数组实际上存的是第f_x 个数组的值,这样可以实现O(1) 交换。
这样算出来暴力实现有效操作为
这是复杂度跑满的代码(可以发现能过):
#include<bits/stdc++.h>
using namespace std;
int a[21][2000003], ta[2000003], tb[2000003], js[23];
bool sd[23];
int jh[23];
int n, m, q;
namespace FastIO {
char buf[1 << 21], *p1 = buf, *p2 = buf;
#define getchar() (p1 == p2 && (p1 = buf, p2 = (p1 + fread(buf, 1, 1 << 21, stdin))) == p1 ? EOF : *p1++)
template <typename T> inline T read() { T x = 0, w = 0; char ch = getchar(); while (ch < '0' || ch > '9') w |= (ch == '-'), ch = getchar(); while ('0' <= ch && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar(); return w ? -x : x; }
template <typename T> inline void write(T x) { if (!x) return; write<T>(x / 10), putchar((x % 10) ^ '0'); }
template <typename T> inline void print(T x) { if (x > 0) write<T>(x); else if (x < 0) putchar('-'), write<T>(-x); else putchar('0'); }
template <typename T> inline void print(T x, char en) { print<T>(x), putchar(en); }
}; using namespace FastIO;
#undef getchar()
int main(){
n = read<int>(), m = read<int>(), q = read<int>();
for (register int i = 1; i <= m; i++)
for (register int j = 1; j <= n; j++)
a[i][j] = read<int>();
for (register int i = 1; i <= m; i++)
jh[i] = i;
while (q--){
int op, x, y;
op = read<int>(), x = read<int>(), y = read<int>();
if (op == 1){
int xx = x, yy = y;
x = jh[x], y = jh[y];
if (!sd[x])
sort(a[x] + 1, a[x] + 1 + n);
if (!sd[y])
sort(a[y] + 1, a[y] + 1 + n);
sd[x] = sd[y] = 1;
js[x]++;
js[y]++;
if ((js[x] > m * m / 2 || js[y] > m * m / 2) && a[x][n] <= a[y][1])
continue;
else if ((js[x] > m * m / 2 || js[y] > m * m / 2) && a[y][n] <= a[x][1]){
swap(jh[xx], jh[yy]);
continue;
}
int p1, p2;
p1 = 1, p2 = 1;
for (register int i = 1; i <= n; i++){
if (p2 > n || (p1 <= n && a[x][p1] < a[y][p2]))
ta[i] = a[x][p1++];
else
ta[i] = a[y][p2++];
}
for (register int i = 1; i <= n; i++){
if (p2 > n || (p1 <= n && a[x][p1] < a[y][p2]))
tb[i] = a[x][p1++];
else
tb[i] = a[y][p2++];
}
for (register int i = 1; i <= n; i++)
a[x][i] = ta[i], a[y][i] = tb[i];
}else{
//x = jh[x];
print(a[jh[x]][y], '\n');
//cout << << "\n";
}
// for (int i = 1; i <= m; i++)
// cout << jh[i] << " ";
// cout << "\n";
// for (int i = 1; i <= m; i++){
// for (int j = 1; j <= n; j++)
// cout << a[i][j] << " ";
// cout << "\n";
// }
}
return 0;
}
这是判断是否有效,有效就交换的代码:
#include<bits/stdc++.h>
using namespace std;
int a[23][2000003], ta[2000003], tb[2000003];
bool sd[23];
int jh[23];
int n, m, q;
namespace FastIO {
char buf[1 << 21], *p1 = buf, *p2 = buf;
#define getchar() (p1 == p2 && (p1 = buf, p2 = (p1 + fread(buf, 1, 1 << 21, stdin))) == p1 ? EOF : *p1++)
template <typename T> inline T read() { T x = 0, w = 0; char ch = getchar(); while (ch < '0' || ch > '9') w |= (ch == '-'), ch = getchar(); while ('0' <= ch && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar(); return w ? -x : x; }
template <typename T> inline void write(T x) { if (!x) return; write<T>(x / 10), putchar((x % 10) ^ '0'); }
template <typename T> inline void print(T x) { if (x > 0) write<T>(x); else if (x < 0) putchar('-'), write<T>(-x); else putchar('0'); }
template <typename T> inline void print(T x, char en) { print<T>(x), putchar(en); }
}; using namespace FastIO;
#undef getchar()
int main(){
n = read<int>(), m = read<int>(), q = read<int>();
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
a[i][j] = read<int>();
for (int i = 1; i <= m; i++)
jh[i] = i;
while (q--){
int op, x, y;
op = read<int>(), x = read<int>(), y = read<int>();
if (op == 1){
int xx = x, yy = y;
// cout << x << " " << y << "\n";
x = jh[x], y = jh[y];
if (!sd[x])
sort(a[x] + 1, a[x] + 1 + n);
if (!sd[y])
sort(a[y] + 1, a[y] + 1 + n);
sd[x] = sd[y] = 1;
// cout << op << " " << x << " " << y << "\n";
// for (int i = 1; i <= m; i++)
// cout << jh[i] << " ";
// cout << "\n\n";
if (a[x][n] <= a[y][1])
continue;
else if (a[y][n] <= a[x][1]){
swap(jh[xx], jh[yy]);
// for (int i = 1; i <= m; i++)
// cout << jh[i] << " ";
// cout << "\n";
continue;
}
// for (int i = 1; i <= m; i++)
// cout << jh[i] << " ";
// cout << "\n";
int p1 = 1, p2 = 1;
for (int i = 1; i <= n; i++){
if (p2 > n || (p1 <= n && a[x][p1] < a[y][p2]))
ta[i] = a[x][p1++];
else
ta[i] = a[y][p2++];
}
for (int i = 1; i <= n; i++){
if (p2 > n || (p1 <= n && a[x][p1] < a[y][p2]))
tb[i] = a[x][p1++];
else
tb[i] = a[y][p2++];
}
for (int i = 1; i <= n; i++)
a[x][i] = ta[i], a[y][i] = tb[i];
}else{
//x = jh[x];
print(a[jh[x]][y], '\n');
//cout << << "\n";
}
// for (int i = 1; i <= m; i++)
// cout << jh[i] << " ";
// cout << "\n";
// for (int i = 1; i <= m; i++){
// for (int j = 1; j <= n; j++)
// cout << a[i][j] << " ";
// cout << "\n";
// }
}
return 0;
}