#include <bits/stdc++.h>
using namespace std;
static const int MOD = 1000000007;
static long long mod_pow(long long a, long long e) {
long long r = 1 % MOD;
a %= MOD;
while (e > 0) {
if (e & 1) r = (r * a) % MOD;
a = (a * a) % MOD;
e >>= 1;
}
return r;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, K;
cin >> N >> K;
vector<int> A(N + 1);
int maxV = 0;
for (int i = 1; i <= N; i++) {
cin >> A[i];
maxV = max(maxV, A[i]);
}
vector<int> P(K);
for (int i = 0; i < K; i++) cin >> P[i];
// Precompute factorials and inverse factorials up to N
vector<long long> fact(N + 1), invfact(N + 1);
fact[0] = 1;
for (int i = 1; i <= N; i++) fact[i] = fact[i - 1] * i % MOD;
invfact[N] = mod_pow(fact[N], MOD - 2);
for (int i = N; i >= 1; i--) invfact[i - 1] = invfact[i] * i % MOD;
auto C = [&](int n, int k) -> long long {
if (k < 0 || k > n) return 0;
return fact[n] * invfact[k] % MOD * invfact[n - k] % MOD;
};
// modular inverse of C(n,k) without pow:
// inv(C(n,k)) = invfact[n] * fact[k] * fact[n-k]
auto invC = [&](int n, int k) -> long long {
if (k < 0 || k > n) return 0;
return invfact[n] * fact[k] % MOD * fact[n - k] % MOD;
};
// Build "right events" in one flat array to avoid 200k vector allocations:
// events for i = segment [evStart[i], evEnd[i]) in evFlat.
vector<int> evStart(N + 2), evEnd(N + 2);
vector<pair<int,int>> evFlat;
evFlat.reserve(2 * N + 5);
vector<int> stIdx; // monotone stack of indices
stIdx.reserve(N);
for (int i = N; i >= 1; i--) {
evStart[i] = (int)evFlat.size();
while (!stIdx.empty() && A[stIdx.back()] > A[i]) {
evFlat.push_back({A[stIdx.back()], -1}); // popped
stIdx.pop_back();
}
evFlat.push_back({A[i], +1}); // pushed
stIdx.push_back(i);
evEnd[i] = (int)evFlat.size();
}
// cntL / cntR are counts of record-minima values on left/right of current p
vector<int> cntL(maxV + 1, 0), cntR(maxV + 1, 0);
// Initialize cntR to record-minima of suffix starting at 1 (stack content after full build)
for (int idx : stIdx) cntR[A[idx]]++;
long long ans = 1; // product of C(L+R, L), initially all L=0 => 1
auto updateValue = [&](int v, int deltaL, int deltaR) {
int oldL = cntL[v];
int oldR = cntR[v];
// remove old contribution
ans = ans * invC(oldL + oldR, oldL) % MOD;
// apply deltas
cntL[v] = oldL + deltaL;
cntR[v] = oldR + deltaR;
int newL = cntL[v];
int newR = cntR[v];
// add new contribution
ans = ans * C(newL + newR, newL) % MOD;
};
vector<long long> M(N + 1);
vector<int> leftStack; // store left record-minima values (monotone non-decreasing stack)
leftStack.reserve(N);
for (int p = 1; p <= N; p++) {
// Move right-suffix start from p to p+1 by applying inverse events of position p
// (events are defined for extending suffix leftward; we undo them to move start rightward)
for (int e = evStart[p]; e < evEnd[p]; e++) {
int v = evFlat[e].first;
int t = evFlat[e].second; // +1 push, -1 pop (in build direction)
updateValue(v, 0, -t);
}
M[p] = ans;
int x = A[p];
while (!leftStack.empty() && leftStack.back() > x) {
updateValue(leftStack.back(), -1, 0);
leftStack.pop_back();
}
updateValue(x, +1, 0);
leftStack.push_back(x);
}
// Output answers for queries
for (int i = 0; i < K; i++) {
if (i) cout << ' ';
cout << M[P[i]];
}
cout << '\n';
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |