제출 #1211930

#제출 시각아이디문제언어결과실행 시간메모리
1211930vaneaZoltan (COCI16_zoltan)C++20
140 / 140
244 ms26300 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll mxN = 1e6+10; const ll MOD = 1e9+7; array<array<ll, 2>, 2> st[mxN]; vector<ll> values; array<ll, 2> comb(array<ll, 2> a, array<ll, 2> b) { array<ll, 2> ans; if(a[0] == b[0]) { ans = {a[0], (a[1]+b[1])%MOD}; } else if(a[0] > b[0]) ans = a; else ans = b; return ans; } array<ll, 2> qry(ll node, ll l, ll r, ll l1, ll r1, ll flag) { if(l1 <= l && r <= r1) { return st[node][flag]; } if(l1 > r || r1 < l) return {0, 0}; ll mid = (l+r)/2; return comb(qry(node*2, l, mid, l1, r1, flag), qry(node*2+1, mid+1, r, l1, r1, flag)); } void upd(ll node, ll l, ll r, ll k, array<ll, 2> x, ll flag) { if(r == l && r == k) { if(x[0] > st[node][flag][0]) { st[node][flag][0] = x[0]; st[node][flag][1] = x[1]; } else if(x[0] == st[node][flag][0]) { st[node][flag][1] = (x[1] + st[node][flag][1]) % MOD; } return ; } if(l > k || r < k) return ; ll mid = (l+r)/2; upd(node*2, l, mid, k, x, flag); upd(node*2+1, mid+1, r, k, x, flag); st[node][flag] = comb(st[node*2][flag], st[node*2+1][flag]); } ll val(ll x) { return lower_bound(values.begin(), values.end(), x)-values.begin(); } ll bin_exp(ll a, ll b) { ll ans = 1; while(b) { if(b & 1) ans = (ans * a) % MOD; a = (a * a) % MOD; b /= 2; } return ans; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); ll n; cin >> n; vector<ll> v(n); for(ll i = 0; i < n; i++) { cin >> v[i]; values.push_back(v[i]); } sort(values.begin(), values.end()); values.erase(unique(values.begin(), values.end()), values.end()); vector<array<ll, 2>> ans1(n), ans2(n); for(ll i = n-1; i >= 0; i--) { v[i] = val(v[i]); array<ll, 2> now = qry(1, 0, values.size()+1, 0, v[i]-1, 0); now[0]++; now[0] %= MOD; if(now[1] == 0) now[1] = 1; ans1[i] = now; upd(1, 0, values.size()+1, v[i], now, 0); } for(ll i = n-1; i >= 0; i--) { array<ll, 2> now = qry(1, 0, values.size()+1, v[i]+1, values.size()+1, 1); now[0]++; now[0] %= MOD; if(now[1] == 0) now[1] = 1; ans2[i] = now; upd(1, 0, values.size()+1, v[i], now, 1); } ll mx = 0; for(ll i = 0; i < n; i++) { mx = max(mx, ans1[i][0]+ans2[i][0]-1); } ll cnt = 0; for(ll i = 0; i < n; i++) { if(ans1[i][0]+ans2[i][0]-1 == mx) { ll now = (ans1[i][1] * ans2[i][1]) % MOD; cnt = (cnt + now) % MOD; } } cnt = (cnt * bin_exp(2, n-mx)) % MOD; cout << mx << ' ' << cnt; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...