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.
Stop staring at all subarrays. Track positions instead: let be the position of value in the permutation.
For , every subarray containing must contain the whole segment from the minimum to maximum of their positions. So MEX appears iff is outside that segment.
Equivalently, when inserting into the relative order of , MEX appears iff the new rank is one of the two extremes.
So each bit contributes independently: for , bit 1 gives choices, while bit 0 gives choices. Also bit must be 1, and bit cannot be 0 for any positive count.
For each ?, start with the smaller positive factor: choose , except at where choosing 0 gives factor . If this minimum product is divisible by , the only useful fix is replacing some factor- choices by odd factors , possible only at even ? positions .
For a permutation , define as the position of value .
For , a subarray has MEX exactly when it contains every value and does not contain . Let Any subarray containing all values below must contain the whole segment .
So if , every such subarray also contains , and MEX is impossible. If , then itself contains all smaller values and avoids , so MEX appears.
Thus MEX appears iff becomes a new leftmost or rightmost position among .
Now count by insertion ranks. Build the relative order of one value at a time. When inserting , its rank among the first positions can be any number from to , and every sequence of insertion ranks maps to exactly one permutation. No hidden dependency. Nice, for once.
For :
Also MEX always appears, because the whole permutation contains all values . Therefore must be 1.
So for a fixed binary string ,
if , and otherwise.
Since is divisible by every positive , any forced zero product is useless. If or , the answer is immediately .
Now minimize the product over replacements of ?.
For each position :
1 contributes ;0 contributes ;? lets us choose between and .The smallest positive choice for a ? is factor at , and factor everywhere else. Let this minimum product be .
If is not divisible by , it is the answer.
Now suppose is divisible by . Changing a ? can only replace the base factor by the other factor. At , this changes to , which only adds a factor of . At odd , replacing by replaces it with an even number, so no prime exponent decreases. At even , replacing by odd decreases the exponent of prime by exactly .
No move can decrease an odd prime exponent. Therefore, once is divisible by , the only way to break divisibility is to reduce the power of below what requires.
Let be the exponent of in , and let be the exponent of in . We need so the minimum number of useful changes is If is odd, or fewer than useful positions exist, no valid string exists.
Each useful change at even ? position replaces by odd , multiplying the product by . These ratios increase with , so the cheapest repair is taking the first such positions.
We maintain modulo . For each selected repair, multiply by and by the modular inverse of .
The algorithm factors , scans the string once, checks divisibility of , and possibly applies the cheapest repairs. Complexity is per test case, where is the number of prime factors of . Memory is .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1000000007;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
vector<int> primes;
vector<bool> comp(31624, false);
for (int i = 2; i <= 31623; ++i) {
if (!comp[i]) {
primes.push_back(i);
if ((ll)i * i <= 31623) {
for (ll j = (ll)i * i; j <= 31623; j += i) comp[j] = true;
}
}
}
int T;
cin >> T;
const ll inv2 = (MOD + 1) / 2;
while (T--) {
int n;
ll c;
string s;
cin >> n >> c >> s;
if (c == 1 || s[0] == '0' || s[n - 1] == '0') {
cout << -1 << '\n';
continue;
}
ll temp = c;
vector<pair<ll, int>> fac;
for (ll p : primes) {
if (p * p > temp) break;
if (temp % p == 0) {
int e = 0;
while (temp % p == 0) {
temp /= p;
++e;
}
fac.push_back({p, e});
}
}
if (temp > 1) fac.push_back({temp, 1});
vector<ll> have(fac.size(), 0);
ll v2 = 0;
ll ans = 1;
vector<int> useful;
auto addFactor = [&](int x) {
ans = ans * x % MOD;
int z = x;
while (z % 2 == 0) {
z /= 2;
++v2;
}
for (int j = 0; j < (int)fac.size(); ++j) {
int y = x;
ll p = fac[j].first;
while (y % p == 0) {
y /= p;
++have[j];
}
}
};
for (int i = 1; i <= n - 1; ++i) {
char ch = s[i - 1];
int factor;
if (ch == '0') {
factor = i - 1;
} else if (ch == '1') {
factor = 2;
} else {
factor = (i == 2 ? 1 : 2);
if (i >= 4 && i % 2 == 0) useful.push_back(i - 1);
}
addFactor(factor);
}
bool divisible = true;
int need2 = 0;
for (int j = 0; j < (int)fac.size(); ++j) {
if (have[j] < fac[j].second) divisible = false;
if (fac[j].first == 2) need2 = fac[j].second;
}
if (!divisible) {
cout << ans << '\n';
continue;
}
if (need2 == 0) {
cout << -1 << '\n';
continue;
}
ll k = v2 - need2 + 1;
if (k > (ll)useful.size()) {
cout << -1 << '\n';
continue;
}
for (int i = 0; i < k; ++i) {
ans = ans * useful[i] % MOD * inv2 % MOD;
}
cout << ans << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1000000007;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
vector<int> primes;
vector<bool> comp(31624, false);
for (int i = 2; i <= 31623; ++i) {
if (!comp[i]) {
primes.push_back(i);
if ((ll)i * i <= 31623) {
for (ll j = (ll)i * i; j <= 31623; j += i) comp[j] = true;
}
}
}
int T;
cin >> T;
const ll inv2 = (MOD + 1) / 2;
while (T--) {
int n;
ll c;
string s;
cin >> n >> c >> s;
if (c == 1 || s[0] == '0' || s[n - 1] == '0') {
cout << -1 << '\n';
continue;
}
ll temp = c;
vector<pair<ll, int>> fac;
for (ll p : primes) {
if (p * p > temp) break;
if (temp % p == 0) {
int e = 0;
while (temp % p == 0) {
temp /= p;
++e;
}
fac.push_back({p, e});
}
}
if (temp > 1) fac.push_back({temp, 1});
vector<ll> have(fac.size(), 0);
ll v2 = 0;
ll ans = 1;
vector<int> useful;
auto addFactor = [&](int x) {
ans = ans * x % MOD;
int z = x;
while (z % 2 == 0) {
z /= 2;
++v2;
}
for (int j = 0; j < (int)fac.size(); ++j) {
int y = x;
ll p = fac[j].first;
while (y % p == 0) {
y /= p;
++have[j];
}
}
};
for (int i = 1; i <= n - 1; ++i) {
char ch = s[i - 1];
int factor;
if (ch == '0') {
factor = i - 1;
} else if (ch == '1') {
factor = 2;
} else {
factor = (i == 2 ? 1 : 2);
if (i >= 4 && i % 2 == 0) useful.push_back(i - 1);
}
addFactor(factor);
}
bool divisible = true;
int need2 = 0;
for (int j = 0; j < (int)fac.size(); ++j) {
if (have[j] < fac[j].second) divisible = false;
if (fac[j].first == 2) need2 = fac[j].second;
}
if (!divisible) {
cout << ans << '\n';
continue;
}
if (need2 == 0) {
cout << -1 << '\n';
continue;
}
ll k = v2 - need2 + 1;
if (k > (ll)useful.size()) {
cout << -1 << '\n';
continue;
}
for (int i = 0; i < k; ++i) {
ans = ans * useful[i] % MOD * inv2 % MOD;
}
cout << ans << '\n';
}
}