#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 time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |