Submission #1312267

#TimeUsernameProblemLanguageResultExecution timeMemory
1312267IskachunŽarulje (COI15_zarulje)C++20
100 / 100
50 ms13392 KiB
//{
#include <iostream>
#include <iomanip>
#include <vector>
#include <array>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <cmath>
#include <numeric>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <climits>
#include <bitset>
#include <functional>
//}
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;

ll binpow (ll a, ll n = mod - 2) {
    ll ans = 1;
    while (n) {
        if (n & 1) ans = ans * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return ans;
}

void solve () {
    int n, k; cin >> n >> k;

    vector<int> a(n + 1);
    int mx = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        mx = max(mx, a[i]);
    }

    vector<int> ask(k);
    for (int &x : ask) cin >> x;


    vector<ll> fact(n + 1), inv(n + 1);
    fact[0] = 1;
    for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % mod;
    inv[n] = binpow(fact[n]);
    for (int i = n; i >= 1; i--) inv[i - 1] = inv[i] * i % mod;

    auto comb = [&] (int n, int k) -> ll {
        if (k < 0 or k > n) return 0;
        return fact[n] * inv[k] % mod * inv[n - k] % mod;
    };

    auto invcomb = [&] (int n, int k) -> ll {
        if (k < 0 or k > n) return 0;
        return inv[n] * fact[k] % mod * fact[n - k] % mod;
    };

    vector<int> st(n + 2), en(n + 2);
    vector<pair<int,int>> ev;
    vector<int> s;

    for (int i = n; i >= 1; i--) {
        st[i] = (int)ev.size();

        while (s.size() and a[s.back()] > a[i]) {
            ev.emplace_back(a[s.back()], -1);
            s.pop_back();
        }

        ev.emplace_back(a[i], 1);
        s.push_back(i);

        en[i] = (int)ev.size();
    }

    vector<int> left(mx + 1), right(mx + 1);
    for (int i : s) right[a[i]]++;

    ll ans = 1;

    auto update = [&] (int v, int one, int two) -> void {
        int l = left[v], r = right[v];
        ans = ans * invcomb(l + r, l) % mod;

        left[v] += one, right[v] += two;

        l = left[v], r = right[v];
        ans = ans * comb(l + r, l) % mod;
    };

    vector<ll> m(n + 1);
    s.clear();

    for (int i = 1; i <= n; i++) {
        for (int j = st[i]; j < en[i]; j++) {
            int x = ev[j].first, y = ev[j].second;
            update(x, 0, -y);
        }

        m[i] = ans;

        int x = a[i];
        while (s.size() and s.back() > x) {
            update(s.back(), -1, 0);
            s.pop_back();
        }

        update(x, 1, 0);
        s.push_back(x);
    }

    for (int i = 0; i < k; i++) {
        cout << m[ask[i]] << '\n';
    }
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int t = 1; //cin >> t;
    while (t--) solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...