제출 #1248867

#제출 시각아이디문제언어결과실행 시간메모리
1248867nlsosadFinancial Report (JOI21_financial)C++20
100 / 100
3739 ms199916 KiB
#include <bits/stdc++.h> #define f first #define s second // #define int long long using namespace std; int a[300005]; struct Node{ int pre, suf, sum, best; }; int inf = -1e9; Node merge(Node p, Node q){ Node c; if(p.pre==inf){ c.pre=inf; }else c.pre = max({p.pre, p.sum + q.pre, p.sum + q.sum}); if(q.suf==inf){ c.suf = q.suf; }else c.suf = max({q.suf, q.sum + p.suf, p.sum + q.sum}); if(p.sum==inf or q.sum==inf){ c.sum = inf; }else c.sum = p.sum + q.sum; c.best = max({p.suf + q.pre, p.best, q.best}); return c; } Node tr[1200001]; void build(int node, int l, int r){ if(l==r){ tr[node] = {inf, inf, inf, inf}; }else{ int mid = (l+r)/2; build(2*node, l, mid); build(2*node+1, mid+1, r); tr[node] = merge(tr[2*node], tr[2*node+1]); } } void update(int node, int l, int r, int p){ if(l==r){ tr[node] = {1, 1, 1, 1}; }else{ int mid = (l+r)/2; if(p<=mid){ update(2*node, l, mid, p); }else update(2*node+1, mid+1, r, p); tr[node] = merge(tr[2*node], tr[2*node+1]); } } Node query(int node, int start, int end, int l, int r){ if(start > r or end < l){ return {inf, inf, inf, inf}; } if(l<=start and end<=r){ return tr[node]; } int mid = (start+end)/2; Node t = query(2*node, start, mid, l, r); Node p = query(2*node+1, mid+1, end, l, r); return merge(t, p); } struct fenwick{ int maxn; vector<int> bit; void resi(int m){ maxn = m; bit.resize(m+1, 0); } void update(int id, int x){ while(id<=maxn){ bit[id] = max(bit[id], x); id += (id & (-id)); } } int query(int id){ int res = 0; while(id>0){ res = max(res, bit[id]); id -= (id & (-id)); } return res; } }; vector<int> mtr[1200001]; fenwick cay[1200001]; void mmerge(vector<int> &a, vector<int> &b, vector<int> &c){ int i = 1; int j = 1; while (i<a.size() and j < b.size()){ if(a[i] > b[j]){ c.push_back(a[i]); i++; }else{ c.push_back(b[j]); j++; } } while(i<a.size()){ c.push_back(a[i]); i++; } while(j<b.size()){ c.push_back(b[j]); j++; } } void mbuild(int node, int l, int r){ if(l==r){ mtr[node].push_back(0); mtr[node].push_back(a[l]); cay[node].resi(1); }else{ int mid = (l+r)/2; mbuild(2*node, l, mid); mbuild(2*node+1, mid+1, r); mtr[node].push_back(0); mmerge(mtr[2*node], mtr[2*node+1], mtr[node]); cay[node].resi(mtr[node].size()-1); } } void mupdate(int node, int l, int r, int p, int x){ if(l==r){ int it = lower_bound(mtr[node].begin()+1, mtr[node].end(), a[p], greater<int>())-mtr[node].begin(); cay[node].update(it, x); }else{ int mid = (l+r)/2; if(p<=mid){ mupdate(2*node, l, mid, p, x); }else mupdate(2*node+1, mid+1, r, p, x); int it = lower_bound(mtr[node].begin()+1, mtr[node].end(), a[p], greater<int>())-mtr[node].begin(); cay[node].update(it, x); } } int mquery(int node, int start, int end, int l, int r, int k){ if(start > r or end < l){ return 0; } if(l<=start and end<=r){ int it = lower_bound(mtr[node].begin()+1, mtr[node].end(), k, greater<int>())-mtr[node].begin(); it--; return cay[node].query(it); } int mid = (start+end)/2; int left = mquery(2*node, start, mid, l, r, k); int right = mquery(2*node+1, mid+1, end, l, r, k); return max(left, right); } int tv[300005]; vector<int> pos[300005]; int range[300005]; signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n, d; cin >> n >> d; map<int, int> mp; for (int i = 1;i<=n;++i){ cin >> a[i]; mp[a[i]] = -1; } int nen = 1; for (auto &i:mp){ i.s = nen++; } for (int i = 1;i<=n;++i){ a[i] = mp[a[i]]; pos[a[i]].push_back(i); tv[i] = i; } sort(tv+1, tv+n+1, [](int p, int q){ return a[p] > a[q]; }); nen--; build(1, 1, n); // update(1, 1, n, 2); // Node test = query(1, 1, n, 1, 2); // cout << test.pre;return 0; int tro = nen; int ll = 1, rr = 1; while(ll<=n){ while(rr<=n and a[tv[ll]]==a[tv[rr]]){ rr++; } for (int i = ll;i<rr;++i){ int p = tv[i]; int l = p, r = n; int sol = p; while(l<=r){ int mid = (l+r)/2; Node c = query(1, 1, n, p, mid); if(c.best<d){ l = mid+1; sol = mid; }else r = mid-1; } int cuoi = sol; if(sol!=n){ cuoi++; } cuoi = min(n, cuoi); range[p] = cuoi; } int p = tv[ll]; while(tro>=a[p]){ for (int j:pos[tro]){ update(1, 1, n, j); } tro--; } ll = rr; } for (int i= 1;i<=n;++i){ // cout << range[i] << ' '; } // cout << '\n'; mbuild(1, 1, n); mupdate(1, 1, n, n, 1); int res = 1; for (int i = n-1;i>=1;--i){ int sol = mquery(1, 1, n, i, range[i], a[i]); // cout << sol << '\n'; mupdate(1, 1, n, i, sol+1); res = max(res, sol+1); int tsol = mquery(1, 1, n, i, range[i], a[i]-1); if(tsol>sol)mupdate(1, 1, n, i, tsol); } cout << res; }
#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...