Submission #1149417

#TimeUsernameProblemLanguageResultExecution timeMemory
1149417nrg_studioŽarulje (COI15_zarulje)C++20
100 / 100
107 ms21064 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define pii pair<int,int> #define f first #define s second #define chmin(a, b) a = min(a,b) #define chmax(a, b) a = max(a,b) #define FOR(i, a, b) for (int i = (a); i < (b); i++) #define F0R(i, a) for (int i = 0; i < (a); i++) #define all(x) x.begin(),x.end() #define v vector ll mod = 1e9+7; ll mul(ll a, ll b) {return a*b%mod;} void mul2(ll& a, ll b) {a = mul(a,b);} ll exp(ll a, ll b) { ll res = 1; while (b) { if (b&1) {res = mul(res,a);} a = mul(a,a); b /= 2; } return res; } const int MAX_N = 2e5; int a[MAX_N], small_l[MAX_N+1], small_r[MAX_N+1], last[MAX_N], join[MAX_N]; v<int> comp[MAX_N]; ll ans[MAX_N+1]; ll fac[MAX_N+1], inv[MAX_N+1]; void calc() { fac[0] = 1; for (int i=1;i<MAX_N+1;i++) {fac[i] = mul(fac[i-1],i);} inv[MAX_N] = exp(fac[MAX_N],mod-2); for (int i=MAX_N;i;i--) {inv[i-1] = mul(inv[i],i);} } ll C(int n, int k) { return mul(fac[n],mul(inv[k],inv[n-k])); } int main() { ios::sync_with_stdio(false); cin.tie(0); calc(); int n, k; cin >> n >> k; stack<int> s, s2; for (int i=0;i<n;i++) { cin >> a[i]; a[i]--; } for (int i=0;i<n;i++) { while (s.size() && a[s.top()]>=a[i]) {s.pop();} small_l[i] = (s.empty() ? -1 : s.top()); while (s2.size() && a[s2.top()]>=a[n-i-1]) {s2.pop();} small_r[n-i-1] = (s2.empty() ? n : s2.top()); s.push(i); s2.push(n-i-1); last[a[i]] = n; ans[i] = 1; join[i] = -1; } small_l[n] = n+1; small_r[n] = 0; for (int i=n-1;i>=0;i--) { if (i<small_l[last[a[i]]]) { if (small_r[i]==small_l[last[a[i]]]) {join[last[a[i]]] = i;} last[a[i]] = i; } comp[last[a[i]]].pb(i); } for (int i=0;i<n;i++) { if (comp[i].empty()) {continue;} reverse(all(comp[i])); int m = comp[i].size(); if (join[i]!=-1) { int tot = m+comp[join[i]].size(); mul2(ans[small_l[i]],C(tot,m)); mul2(ans[small_l[i]+1],exp(C(tot,m),mod-2)); } for (int j=0;j<m;j++) { mul2(ans[comp[i][j]],C(m-1,j)); mul2(ans[comp[i][j]+1],exp(C(m-1,j),mod-2)); if (j && comp[i][j]-1 != comp[i][j-1]) { mul2(ans[comp[i][j-1]+1],C(m,j)); mul2(ans[comp[i][j]],exp(C(m,j),mod-2)); } } } for (int i=0;i<n;i++) { mul2(ans[i+1],ans[i]); } while (k--) { int p; cin >> p; cout << ans[p-1] << '\n'; } /* assume this light is left of range then find nearest strictly small_ler value you can turn of until there, if an L and R range of same energy lightbulbs intersect, then any point inside them can reach this state, and has two options from here (biconditional) Find all components of L R intersection, then calc for each point and subrange in the component, with prefix multiplication/mod inverse division, and then sweep through once to get answer question: how to calc answer for a component have L points on left, R points on right it should be (L+R) choose L this means that we only need nearest small_ler values on either R or L */ }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...