제출 #824981

#제출 시각아이디문제언어결과실행 시간메모리
824981phoenixFinancial Report (JOI21_financial)C++17
100 / 100
543 ms42100 KiB
#include<bits/stdc++.h> using namespace std; using ll = long long; const int N = (1 << 19); const int INF = 1e9; int n, d; int a[N]; vector<int> mx(2 * N, -INF); void update(int pos, int val) { for(mx[pos += N] = val; pos > 1; pos >>= 1) { mx[pos >> 1] = max(mx[pos], mx[(pos ^ 1)]); } } // last index i < qr a[i] > val int left_bound(int qr, int val, int l = 0, int r = N - 1, int v = 1) { if(l >= qr || mx[v] <= val) return -1; if(l == r) return l; int m = (l + r) / 2; int res = left_bound(qr, val, m + 1, r, 2 * v + 1); if(res == -1) res = left_bound(qr, val, l, m, 2 * v); return res; } // first index i > ql a[i] > val int right_bound(int ql, int val, int l = 0, int r = N - 1, int v = 1) { if(r <= ql || mx[v] <= val) return -1; if(l == r) return l; int m = (l + r) / 2; int res = right_bound(ql, val, l, m, 2 * v); if(res == -1) res = right_bound(ql, val, m + 1, r, 2 * v + 1); return res; } void add(int pos) { // cout << "add: \n"; int lb = left_bound(pos, -INF), rb = right_bound(pos, -INF); // cout << pos << ' ' << lb << ' ' << rb << '\n'; if(rb != -1) update(rb, rb - pos); update(pos, (lb != -1 ? pos - lb : 0)); } int get_rb(int pos) { int x = right_bound(pos, d); if(x == -1) x = n + 1; return min(left_bound(x, -INF) + d, n); } int st[2 * N]; void insert(int pos, int val, int i) { for(st[pos += N] = val; pos > 1; pos >>= 1) { st[pos >> 1] = max(st[pos], st[(pos ^ 1)]); } } void erase(int pos, int val, int i) { for(st[pos += N] = 0; pos > 1; pos >>= 1) { st[pos >> 1] = max(st[pos], st[(pos ^ 1)]); } } int get(int ql, int qr) { int res = 0; for(ql += N, qr += N + 1; ql < qr; ql >>= 1, qr >>= 1) { if(ql & 1) { res = max(res, st[ql]); ql++; } if(qr & 1) { qr--; res = max(res, st[qr]); } } return res; } vector<int> cl[N]; void compress() { map<int, int> mp; for(int i = 1; i <= n; i++) mp[a[i]] = 1; int k = 0; for(auto &c : mp) c.second = k++; for(int i = 1; i <= n; i++) a[i] = mp[a[i]]; } int main() { ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); cin >> n >> d; for(int i = 1; i <= n; i++) cin >> a[i]; compress(); vector<pair<int, int>> order; for(int i = 1; i <= n; i++) { order.push_back({a[i], i}); } int rb[n + 1] = {}, b[n + 1]; sort(order.begin(), order.end(), [](pair<int, int> x, pair<int, int> y) { if(x.first == y.first) return x.second > y.second; return x.first < y.first; }); int ki = 0; for(auto [a, i] : order) { add(i); rb[i] = get_rb(i); b[i] = ki++; } vector<int> dp(n + 1, 1); for(int i = 1; i <= n; i++) { for(int j : cl[i]) erase(b[j], dp[j], j); dp[i] = get(0, b[i] - 1) + 1; insert(b[i], dp[i], i); cl[rb[i] + 1].push_back(i); } cout << *max_element(dp.begin(), dp.end()); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...