Twlight!
2024-09-07 20:18:24
给定两种
在这里提供一种特别简单的写法以及思路。
先说一个结论,若
(这里以及后文钦定
拿一种
6 2 3 1 8 4 5 7
6 2 1 4 8 3 5 7
(我们查找 3 的位置)
则 i = 3, j = 5
当
根据题目要求的单调不降性质,我们有:
再由不等式的性质,我们便可以得到:
同样地,因为一定存在两个数的对应位置分别满足
到此就证明了一开始的结论。
(因为本人能力有限,不清楚更严谨的证明过程,如果有更好的思路话也可以补充一下。)
那么知道了上述的结论,你可以尝试找到所有
如果你整理这些等式链,你会发现原序列被这些相等关系拆成了若干条区间,每个区间里的字符都相等,而区间与区间之间的字符必须满足字母单调不降,于是就做完了。
由等式链的性质,你只需要扫一遍
求出了不同的区间后,怎么构造字符串和判断是否有解就不再赘述,看代码即可。
时间复杂度:
#include <iostream>
#include <algorithm>
#include <cstdlib>
const int N = 200000 + 10;
using namespace std;
int read() {
int x = 0, k = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') k = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x * k;
}
int n, k;
int p[N], q[N], rkp[N], rkq[N];
int Rng[N], cnt;
char c[N];
signed main() {
n = read(), k = read();
for (int i = 1; i <= n; ++i) p[i] = read(), rkp[p[i]] = i;
for (int i = 1; i <= n; ++i) q[i] = read(), rkq[q[i]] = i;
for (int i = 1, j = 0; i <= n; ++i) {
j = max(j, rkq[p[i]]);
j = max(j, rkp[q[i]]);
if (j == i) Rng[++cnt] = i;
}
if (cnt < k) printf("NO\n"), exit(0);
printf("YES\n");
for (int i = 1, j = 1; i <= n; ++i) {
if (i > Rng[j]) ++j;
c[p[i]] = 'a' + min(k, j) - 1;
}
printf("%s\n", c + 1);
return 0;
}
顺着这个思路走,其实代码实现非常的简单,而且运行时间也比较快,大概只有