Submission #1282346

#TimeUsernameProblemLanguageResultExecution timeMemory
1282346c4lTeam Contest (JOI22_team)C++20
0 / 100
925 ms1114112 KiB
#include <bits/stdc++.h> #define int long long using namespace std; struct mem{ int x, y, z; }; mem a[150001]; vector<int> luu[600005]; vector<pair<int, int>> tr[600005]; int inf = (int)(-1e18); struct pst{ struct Node{ int val; int l, r; Node(int v){ val = v; l = -1, r= -1; } }; vector<Node> luu; void clear(){ luu.clear(); } int build(int start, int end){ if(start==end){ Node tmp(inf); luu.push_back(tmp); return (int)luu.size()-1; }else{ int mid = (start+end)/2; Node tmp(inf); int t = build(start, mid); int p = build(mid+1, end); tmp.l = t, tmp.r = p; luu.push_back(tmp); return (int)luu.size()-1; } } int update(int start, int end, int p, int x, int id){ if(start==end){ Node tmp(0); tmp.val = luu[id].val; tmp.val = max(tmp.val, x); luu.push_back(tmp); return (int)luu.size()-1; }else{ int mid = (start+end)/2; Node tmp(0); tmp.val = luu[id].val; tmp.l = luu[id].l, tmp.r = luu[id].r; if(p<=mid){ int tr = update(start, mid, p, x, luu[id].l); tmp.l = tr; }else{ int tr = update(mid+1, end, p, x, luu[id].r); tmp.r = tr; } tmp.val = max(luu[tmp.l].val, luu[tmp.r].val); luu.push_back(tmp); return (int)luu.size()-1; } } int query(int start, int end, int l, int r, int id){ if(start > r or end < l) return inf; if(l<=start and end<=r){ return luu[id].val; } int mid = (start+end)/2; return max(query(start, mid, l, r, luu[id].l), query(mid+1,end, l, r, luu[id].r)); } }; pst cay[600005]; vector<int> seg[600005]; vector<int> pf[600005], lz[600005]; //X void merge(vector<pair<int, int>> &A, vector<pair<int, int>> &B, vector<pair<int, int>> &C, int node){ int i = 1, j = 1; int na = (int)A.size(), nb = (int)B.size(); while(i<na && j<nb){ if(A[i] < B[j]){ C.push_back(A[i]); pf[node].push_back(pf[2*node][i]); i++; }else{ C.push_back(B[j]); pf[node].push_back(pf[2*node+1][j]); j++; } } while(i<na){ C.push_back(A[i]); pf[node].push_back(pf[2*node][i]); i++; } while(j<nb){ C.push_back(B[j]); pf[node].push_back(pf[2*node+1][j]); j++; } } void merge2(vector<int> &A, vector<int> &B, vector<int> &C){ int i = 1, j = 1; int na = (int)A.size(), nb = (int)B.size(); while(i<na && j<nb){ if(A[i] < B[j]){ C.push_back(A[i]); i++; }else{ C.push_back(B[j]); j++; } } while(i<na){ C.push_back(A[i]); i++; } while(j<nb){ C.push_back(B[j]); j++; } } void reset(int node, int start, int end){ tr[node].clear(); luu[node].clear(); pf[node].clear(); lz[node].clear(); seg[node].clear(); cay[node].clear(); if(start!=end){ int mid = (start+end)/2; reset(2*node, start, mid); reset(2*node+1, mid+1, end); } } void build(int node, int start, int end){ tr[node].push_back({-1,-1}); luu[node].push_back(-1); pf[node].push_back(-1); lz[node].push_back(-1); if(start==end){ pf[node].push_back(a[start].x); tr[node].push_back({a[start].y, a[start].z}); luu[node].push_back(a[start].z); lz[node].push_back(a[start].z); int m = (int)tr[node].size()-1; int root = cay[node].build(1, m); seg[node].push_back(root); for (int i = 1;i<=m;++i){ int p = (int)(lower_bound(luu[node].begin()+1, luu[node].end(), tr[node][i].second) - luu[node].begin()); // p should be in [1..m] if(p<1) p = 1; int nr = cay[node].update(1, m, p, pf[node][i], seg[node].back()); seg[node].push_back(nr); } }else{ int mid = (start+end)/2; build(2*node, start, mid); build(2*node+1, mid+1, end); merge(tr[2*node], tr[2*node+1], tr[node], node); merge2(luu[2*node], luu[2*node+1], luu[node]); int m= (int)tr[node].size()-1; int root = cay[node].build(1, m); seg[node].push_back(root); for (int i = 1;i<=m;++i){ int p = (int)(lower_bound(luu[node].begin()+1, luu[node].end(), tr[node][i].second) - luu[node].begin()); if(p<1) p = 1; int nr = cay[node].update(1, m, p, pf[node][i], seg[node].back()); seg[node].push_back(nr); } for (int i = 1;i<=m;++i){ lz[node].push_back(tr[node][i].second); lz[node][i] = max(lz[node][i], lz[node][i-1]); } } } int q1(int node, int start, int end, int l, int r, int y){ if(start > r or end < l){ return -1; }else if (l<=start and end<=r){ // search among real elements (1..size-1) auto it = lower_bound(tr[node].begin()+1, tr[node].end(), make_pair((int)y, (int)-1)); int p = (int)(it - tr[node].begin()) - 1; // p in [0..m] if(p < 0) p = 0; return lz[node][p]; }else{ int mid= (start+end)/2; return max(q1(2*node, start, mid, l, r, y), q1(2*node+1, mid+1, end, l, r, y)); } } int q2(int node, int start, int end, int l, int r, int y, int z){ if(start > r or end < l){ return inf; } if(l<=start and end<=r){ auto it = lower_bound(tr[node].begin()+1, tr[node].end(), make_pair((int)y, (int)-1)); int p = (int)(it - tr[node].begin()) - 1; // p in [0..m] if(p < 0) p = 0; int m = (int)tr[node].size()-1; auto it2 = lower_bound(luu[node].begin()+1, luu[node].end(), z); int q = (int)(it2 - luu[node].begin()) - 1; // we want last index <= z if(q < 1) return inf; // nothing <= z int sol = cay[node].query(1, m, 1, q, seg[node][p]); return sol; } int mid = (start+end)/2; return max(q2(2*node, start, mid, l, r, y, z), q2(2*node+1, mid+1, end, l, r, y, z)); } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n; if(!(cin >> n)) return 0; for (int i = 1;i<=n;++i){ cin >> a[i].x >> a[i].y >> a[i].z; } sort(a+1, a+n+1, [](mem p, mem q){ return p.x < q.x; }); int tro = 1; build(1, 1, n); int res = -1; for (int i = 2;i<=n;++i){ while(tro<=n and a[tro].x<=a[i].x){ tro++; } int mz = q1(1, 1, n, 1, i-1, a[i].y); if(mz != -1){ int sol = q2(1, 1, n, tro, n, a[i].y, mz); if(sol!=inf){ res = max(res, a[i].y + mz + sol); } } } reset(1, 1, n); for (int i = 1;i<=n;++i){ swap(a[i].y, a[i].z); } tro = 1; build(1, 1, n); for (int i = 2;i<=n;++i){ while(tro<=n and a[tro].x<=a[i].x){ tro++; } int mz = q1(1, 1, n, 1, i-1, a[i].y); if(mz != -1){ int sol = q2(1, 1, n, tro, n, a[i].y, mz); if(sol!=inf){ res = max(res, a[i].y + mz + sol); } } } 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...
#Verdict Execution timeMemoryGrader output
Fetching results...