Unforgivable Curse (hard version)
用并查集维护可以互相交换的位置的集合,然后判断这个集合位置中s和t中的字符集是否是相同的
#include <bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using i64 = long long;
struct DSU {
std::vector<int> f, siz;
DSU() {}
DSU(int n) {
init(n);
}
void init(int n) {
f.resize(n);
std::iota(f.begin(), f.end(), 0);
siz.assign(n, 1);
}
int find(int x) {
while (x != f[x]) {
x = f[x] = f[f[x]];
}
return x;
}
bool same(int x, int y) {
return find(x) == find(y);
}
bool merge(int x, int y) {
x = find(x);
y = find(y);
if (x == y) {
return false;
}
siz[x] += siz[y];
f[y] = x;
return true;
}
int size(int x) {
return siz[find(x)];
}
};
void solve() {
int n;
std::cin >> n;
int k;
std::cin >> k;
std::string s, t;
std::cin >> s >> t;
DSU p(n + 1);
for (int i = 1; i <= n; i ++) {
if (i + k <= n) {
p.merge(i, i + k);
}
if (i + k + 1 <= n) {
p.merge(i, i + k + 1);
}
}
std::map<int, int> mp1;
std::vector<std::set<int>> S(n + 1);
for (int i = 1; i <= n; i ++) {
S[p.find(i)].insert(i);
}
for (int i = 1; i <= n; i ++) {
if (S[p.find(i)].size()) {
std::string tmps, tmpt;
for (auto x : S[p.find(i)]) {
tmps += s[x - 1];
tmpt += t[x - 1];
}
sort(tmps.begin(), tmps.end());
sort(tmpt.begin(), tmpt.end());
if (tmps != tmpt) {
std::cout << "No\n";
return;
}
S[p.find(i)].clear();
}
}
std::cout << "YES\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}