/*
Problem: Can we transform string M into string C using restricted swaps?
You have two strings M and C of the same length n.
You can swap characters in M at positions that are exactly distance d or d+1 apart.
Question: Can you transform M into C using these swaps?
Example:
M = "abc", C = "bca", d = 1
- You can swap positions 0 and 1 (distance 1): "abc" -> "bac"
- You can swap positions 0 and 2 (distance 2 = d+1): "bac" -> "cab"
- You can swap positions 1 and 2 (distance 1): "cab" -> "cba"
- Keep going... eventually you can reach "bca" → YES
==================================================================================
HOW WE SOLVE THIS:
==================================================================================
KEY INSIGHT: If two positions can be connected through a chain of swaps,
then we can rearrange characters between those positions however we want!
Think of it like this:
- Position i can swap with position i+d and position i+d+1
- Position i+d can swap with position i+2d and position i+2d+1
- And so on...
So some positions form "groups" where characters can move freely within the group.
APPROACH:
1. Build groups of positions that are connected by swaps
- Use DSU (Disjoint Set Union) / Union-Find data structure
- Connect position i with i+d (if it exists)
- Connect position i with i+d+1 (if it exists)
2. For each group, check if transformation is possible:
- Collect all characters from M at those positions
- Collect all characters from C at those positions
- Sort both collections
- If they match → we can rearrange M's characters to match C's characters
- If they don't match → impossible (we'd need different characters)
3. If ALL groups can be transformed, answer is YES
Otherwise, answer is NO
Example walkthrough:
M = "abc", C = "bca", n = 3, d = 1
Step 1: Build connections
- Position 0 connects to 0+1=1 and 0+2=2
- Position 1 connects to 1+1=2
- Position 2 has no further connections
Result: All positions 0,1,2 are in one group!
Step 2: Check if transformation is possible
- Characters in M at positions {0,1,2}: {'a','b','c'} → sorted: "abc"
- Characters in C at positions {0,1,2}: {'b','c','a'} → sorted: "abc"
- They match! ✓
Answer: YES
Why this works:
If two positions are in the same group, we can swap characters between them
(possibly through intermediate swaps). So we can arrange characters in that
group in ANY order we want. We just need to have the right characters available.
Time complexity: O(n × α(n)) for DSU operations, where α is inverse Ackermann
O(n log n) for sorting in the worst case
Space complexity: O(n) for storing groups and DSU structure
==================================================================================
*/
#include <bits/stdc++.h>
using namespace std;
// Union-Find / Disjoint Set Union data structure
// Helps us group positions that can exchange characters
struct UnionFind {
vector<int> boss; // boss[i] = leader of the group containing position i
vector<int> depth; // depth[i] = approximate depth of tree rooted at i
UnionFind(int n = 0) {
setup(n);
}
void setup(int n) {
boss.resize(n);
depth.assign(n, 0);
// Initially, each position is its own boss (separate group)
for(int i = 0; i < n; i++) {
boss[i] = i;
}
}
// Find the boss/leader of the group containing position i
int find_boss(int i) {
if(boss[i] == i) {
return i; // i is the boss
}
// Path compression: make i point directly to boss for faster future queries
return boss[i] = find_boss(boss[i]);
}
// Merge the groups containing positions a and b
void connect(int a, int b) {
a = find_boss(a);
b = find_boss(b);
if(a == b) return; // Already in same group
// Union by depth: attach smaller tree under larger tree
if(depth[a] < depth[b]) {
swap(a, b);
}
boss[b] = a;
if(depth[a] == depth[b]) {
depth[a]++;
}
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, d;
cin >> n >> d;
string start_string, goal_string;
cin >> start_string >> goal_string;
// Build groups of positions that can exchange characters
UnionFind uf(n);
for(int i = 0; i < n; i++){
// Position i can swap with position i + d
if(i + d < n) {
uf.connect(i, i + d);
}
// Position i can also swap with position i + d + 1
if(i + d + 1 < n) {
uf.connect(i, i + d + 1);
}
}
// Group positions by their boss (leader)
// boss_to_positions[boss] = list of all positions with that boss
unordered_map<int, vector<int>> boss_to_positions;
for(int i = 0; i < n; i++) {
int boss = uf.find_boss(i);
boss_to_positions[boss].push_back(i);
}
// Check each group: can we rearrange characters to match?
for(auto& [boss, positions] : boss_to_positions){
// Collect characters from start_string at these positions
vector<char> start_chars;
start_chars.reserve(positions.size());
for(int pos : positions){
start_chars.push_back(start_string[pos]);
}
// Collect characters from goal_string at these positions
vector<char> goal_chars;
goal_chars.reserve(positions.size());
for(int pos : positions){
goal_chars.push_back(goal_string[pos]);
}
// Sort both to compare
// If they have the same characters (in any order), we can rearrange
sort(start_chars.begin(), start_chars.end());
sort(goal_chars.begin(), goal_chars.end());
// If the characters don't match, transformation is impossible
if(start_chars != goal_chars){
cout << "NO\n";
return 0;
}
}
// All groups can be transformed successfully!
cout << "YES\n";
return 0;
}