제출 #419653

#제출 시각아이디문제언어결과실행 시간메모리
419653alishahali1382Financial Report (JOI21_financial)C++14
100 / 100
636 ms23872 KiB
#include <bits/stdc++.h> #pragma GCC optimize("O2") using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef long double ld; typedef pair<pii, int> piii; #define debug(x) {cerr<<#x<<"="<<x<<"\n";} #define debug2(x, y) {cerr<<"{"<<#x<<", "<<#y<<"}={"<<x<<", "<<y<<"}\n";} #define debugp(p) {cerr<<#p<<"={"<<p.first<<" "<<p.second<<"}\n";} #define debugv(abcd) {cerr<<#abcd<<": ";for (auto dcba:abcd) cerr<<dcba<<" ";cerr<<"\n";} #define pb push_back #define all(x) x.begin(), x.end() #define kill(x) return cout<<x<<"\n", 0; #define SZ(x) ((int)x.size()) const int inf=1000010000; const int mod=1000000007; const int MAXN=300010; struct Node{ int pref, suff, ans; bool full; } seg[MAXN<<2]; Node getNode(int x){ Node tmp; tmp.pref=tmp.suff=tmp.ans=tmp.full=x; return tmp; } Node operator +(Node X, Node Y){ Node Z; Z.pref=X.pref+(X.full?Y.pref:0); Z.suff=(Y.full?X.suff:0)+Y.suff; Z.ans=max({X.ans, Y.ans, X.suff+Y.pref}); Z.full=X.full&Y.full; return Z; } int n, m, q, k, u, v, x, y, t, l, r, ans; int A[MAXN], dp[MAXN]; pii comp[MAXN]; Node Build(int id, int tl, int tr){ if (tr-tl==1) return seg[id]=getNode(1); int mid=(tl+tr)>>1; return seg[id]=Build(id<<1, tl, mid)+Build(id<<1 | 1, mid, tr); } void Set(int id, int tl, int tr, int pos, int x){ if (pos<tl || tr<=pos) return ; if (tr-tl==1){ seg[id]=getNode(x); return ; } int mid=(tl+tr)>>1; Set(id<<1, tl, mid, pos, x); Set(id<<1 | 1, mid, tr, pos, x); seg[id]=seg[id<<1] + seg[id<<1 | 1]; } Node Get(int id, int tl, int tr, int l, int r){ if (r<=tl || tr<=l) return seg[0]; if (l<=tl && tr<=r) return seg[id]; int mid=(tl+tr)>>1; return Get(id<<1, tl, mid, l, r) + Get(id<<1 | 1, mid, tr, l, r); } pair<Node, int> BS(int id, int tl, int tr, int l, int r, Node X){ if (r<=tl || tr<=l) return {X, tl}; if (l<=tl && tr<=r){ if ((seg[id]+X).ans<k) return {seg[id]+X, tl}; if (tr-tl==1) return {X, tr}; int mid=(tl+tr)>>1; auto p=BS(id<<1 | 1, mid, tr, l, r, X); if (mid<p.second) return p; return BS(id<<1, tl, mid, l, r, p.first); } int mid=(tl+tr)>>1; auto p=BS(id<<1 | 1, mid, tr, l, r, X); if (mid<p.second) return p; return BS(id<<1, tl, mid, l, r, p.first); } struct Segment2{ int seg[MAXN<<1]; void Set(int pos, int val){ for (seg[pos+=n]=val; pos>1; pos>>=1) seg[pos>>1]=max(seg[pos], seg[pos^1]); } int Get(int l, int r){ int res=0; for (l+=n, r+=n; l<r; l>>=1, r>>=1){ if (l&1) res=max(res, seg[l++]); if (r&1) res=max(res, seg[--r]); } return res; } } seg2; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); seg[0].full=1; cin>>n>>k; for (int i=1; i<=n; i++) cin>>A[i], comp[i]={A[i], -i}; sort(comp+1, comp+n+1); for (int i=1; i<=n; i++) A[-comp[i].second]=i; // cerr<<"A: ";for (int i=1; i<=n; i++) cerr<<A[i]<<" \n"[i==n]; Build(1, 1, n+1); for (int ii=1; ii<=n; ii++){ int i=-comp[ii].second; Set(1, 1, n+1, i, 0); /* int dwn=0, up=i; while (up-dwn>1){ int mid=(dwn+up)>>1; if (Get(1, 1, n+1, mid, i).ans>=k) dwn=mid; else up=mid; }*/ int up=BS(1, 1, n+1, 1, i, seg[0]).second; // for (int j=up; j<i; j++) dp[i]=max(dp[i], dp[j]); dp[i]=seg2.Get(up, i); dp[i]++; seg2.Set(i, dp[i]); ans=max(ans, dp[i]); } cout<<ans<<"\n"; return 0; } /* 7 1 1 6 6 2 3 5 5 6 6 100 500 200 400 600 300 */
#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...