Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Don’t try to simulate the operations. A number can move forever, and simulation is a trap with a mustache.
Adding or subtracting means the value usually keeps the same remainder modulo .
The only “weird” move is when : then can become . In modulo terms, that changes remainder into .
So every number belongs to a bucket determined by the pair of remainders and , where .
Use the canonical bucket id for every element. Then can become iff the multisets of these ids are equal.
We need decide whether each element of can be independently transformed so that the final multiset becomes .
The important word is independently. Operations only replace one number with another number. They never split, merge, copy, or delete elements. So this is really asking:
For each number, what set of numbers can it reach?
Then we just compare how many elements from each reachable “type” appear in and .
Understanding The Operation
From a number , we may replace it with either:
or
If , then:
So for large enough values, we can move by or . That means the remainder modulo stays the same.
Example with :
All of these are congruent to .
So far, this screams “compare modulo ”. But there is one catch.
The Catch: Small Numbers Reflect
If , then:
So a small remainder can become .
For example, if :
So remainder and remainder are connected.
More generally, if a number has remainder , we can reduce it down to by subtracting repeatedly. Then from , we can go to .
That means remainder and remainder are in the same reachable group.
Reachability Class
For a number , let:
The number can reach values whose remainders are either:
or
So the whole reachable class can be represented by:
This works nicely for edge cases too:
This canonical value is the only thing that matters.
Why Comparing Buckets Is Enough
Suppose an element of has canonical value . It can only ever become numbers with the same canonical value .
So if has three elements in bucket , then must also have exactly three elements in bucket . Otherwise, no amount of button-mashing fixes it.
Conversely, if every bucket count matches, then we can match each element of to some element of in the same bucket. Since numbers in the same bucket are mutually reachable, every matched element can be transformed correctly.
Therefore:
Convert every number into . Sort both arrays and compare.
Algorithm
For each test case:
Read and .
For every element in , compute:
Do the same for every element in .
Sort both transformed arrays.
If they are equal, print YES; otherwise print NO.
Complexity
For each test case, sorting dominates:
The total over all test cases is at most , so this is easily fine.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
ll k;
cin >> n >> k;
vector<ll> a(n), b(n);
for (ll &x : a) {
cin >> x;
ll r = x % k;
x = min(r, k - r);
}
for (ll &x : b) {
cin >> x;
ll r = x % k;
x = min(r, k - r);
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
cout << (a == b ? "YES" : "NO") << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
ll k;
cin >> n >> k;
vector<ll> a(n), b(n);
for (ll &x : a) {
cin >> x;
ll r = x % k;
x = min(r, k - r);
}
for (ll &x : b) {
cin >> x;
ll r = x % k;
x = min(r, k - r);
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
cout << (a == b ? "YES" : "NO") << '\n';
}
return 0;
}