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.
Compare coefficients of . In the twin polynomial, the coefficient of is the sum of all indices with , so cool means
The value is special: index contributes , so it never affects the twin polynomial. Once are chosen, is forced to be the sum of all positive indices with .
For every positive index , only three things can happen: , , or and for some . In other words, positive indices are zeros, fixed points, or matched pairs.
Known values are forced states. forces vertex to be a zero, forces a fixed point, and forces the pair . Any vertex forced two different ways means answer .
After removing all forced vertices, the untouched vertices are just a matching problem with two singleton colors. If counts free labeled vertices, then Finally, subtract the cases where vertex is zero if was still free.
Compare coefficients of the same power of .
The coefficient of in is the sum of all positive indices whose coefficient value is exactly . The term contributes zero, so it does not matter inside .
So a cool polynomial satisfies
for every .
Also, no positive index may have . If and , then has a positive coefficient at degree , while has no such term. Dead.
Key structure
For every , exactly one of these happens:
So every positive index is either sent to zero, fixed by itself, or paired in a 2-cycle. No longer cycles, no weird piles, no polynomial astrology.
Why this is true: take the smallest positive index that does not fit those cases. Look at the positive indices with .
If there are none, then , so it fits.
If there is exactly one, say , then . If , it is fixed. Otherwise , so and are paired. It fits again.
If there are at least two, then To make the coefficient equation for this larger value work, it would need support from smaller positive indices. But all smaller positive indices already fit the three-case structure, so they only contribute to , themselves, or their paired partner. They cannot create this new messy value. Contradiction.
Therefore the polynomial problem becomes a graph problem on vertices :
zero, meaning ;fixed, meaning ;Vertex cannot be zero, because the polynomial must have degree , so .
What about ? After choosing states for , it is forced:
This is always a valid non-negative integer. It may be bigger than , and that is fine.
Processing fixed input values
For each known with :
zero;fixed;If one vertex receives two different forced states, the answer is .
After all forced states are processed, count the untouched vertices.
Let be the number of ways to arrange labeled free vertices, where each vertex is either a zero singleton, a fixed singleton, or matched with another vertex.
Base cases:
For , take one vertex:
So
If vertex was already forced to be non-zero, the answer is just where is the number of still-free vertices.
If vertex is still free, count all arrangements and subtract the bad ones where is the zero singleton. If there are free vertices including , then the answer is
Everything is modulo .
The total complexity is per test case after precomputing up to .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll MOD = 1000000007LL;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
vector<pair<int, vector<ll>>> tests;
tests.reserve(T);
int maxN = 0;
for (int tc = 0; tc < T; tc++) {
int n;
cin >> n;
maxN = max(maxN, n);
vector<ll> a(n + 1);
for (int i = 0; i <= n; i++) cin >> a[i];
tests.push_back({n, move(a)});
}
vector<ll> dp(maxN + 1);
dp[0] = 1;
if (maxN >= 1) dp[1] = 2;
for (int i = 2; i <= maxN; i++) {
dp[i] = (2 * dp[i - 1] + (ll)(i - 1) * dp[i - 2]) % MOD;
}
for (auto &[n, a] : tests) {
vector<ll> forced(n + 1, -1);
bool ok = true;
auto forceValue = [&](int idx, ll val) {
if (!ok) return;
if (forced[idx] == -1) forced[idx] = val;
else if (forced[idx] != val) ok = false;
};
for (int i = 1; i <= n && ok; i++) {
if (a[i] == -1) continue;
if (a[i] > n) {
ok = false;
break;
}
ll v = a[i];
forceValue(i, v);
if (v > 0 && v != i) {
forceValue((int)v, i);
}
}
if (!ok || forced[n] == 0) {
cout << 0 << '\n';
continue;
}
int freeCnt = 0;
for (int i = 1; i <= n; i++) {
if (forced[i] == -1) freeCnt++;
}
ll ans;
if (forced[n] == -1) {
ans = (dp[freeCnt] - dp[freeCnt - 1] + MOD) % MOD;
} else {
ans = dp[freeCnt];
}
cout << ans << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll MOD = 1000000007LL;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
vector<pair<int, vector<ll>>> tests;
tests.reserve(T);
int maxN = 0;
for (int tc = 0; tc < T; tc++) {
int n;
cin >> n;
maxN = max(maxN, n);
vector<ll> a(n + 1);
for (int i = 0; i <= n; i++) cin >> a[i];
tests.push_back({n, move(a)});
}
vector<ll> dp(maxN + 1);
dp[0] = 1;
if (maxN >= 1) dp[1] = 2;
for (int i = 2; i <= maxN; i++) {
dp[i] = (2 * dp[i - 1] + (ll)(i - 1) * dp[i - 2]) % MOD;
}
for (auto &[n, a] : tests) {
vector<ll> forced(n + 1, -1);
bool ok = true;
auto forceValue = [&](int idx, ll val) {
if (!ok) return;
if (forced[idx] == -1) forced[idx] = val;
else if (forced[idx] != val) ok = false;
};
for (int i = 1; i <= n && ok; i++) {
if (a[i] == -1) continue;
if (a[i] > n) {
ok = false;
break;
}
ll v = a[i];
forceValue(i, v);
if (v > 0 && v != i) {
forceValue((int)v, i);
}
}
if (!ok || forced[n] == 0) {
cout << 0 << '\n';
continue;
}
int freeCnt = 0;
for (int i = 1; i <= n; i++) {
if (forced[i] == -1) freeCnt++;
}
ll ans;
if (forced[n] == -1) {
ans = (dp[freeCnt] - dp[freeCnt - 1] + MOD) % MOD;
} else {
ans = dp[freeCnt];
}
cout << ans << '\n';
}
return 0;
}