在我们要维护形如\(x_i>x_j\land y_i>y_j\)(或\(x_i\ge x_j\land y_i\ge y_j\))的条件时,可以将所有\((x_i,y_i)\)以x为第一关键字,y为第二关键字进行排序。那么在顺序处理时,\(x_i>x_j\)已经满足,只需满足\(y_i>y_j\),则可用线段树或树状数组维护。
#include <bits/stdc++.h>
using namespace std;
struct segetree {
int l,r,tmp1,tmp2;
long long tmp3;
struct segenode {
segenode *ls,*rs;
long long v;
segenode() {ls=rs=NULL,v=0;}
} Root;
void edi(segenode *k,const int l,const int r) {
if (l==r) return void(k->v=tmp3);
if (tmp1<=(l+r)/2)
edi((k->ls?k->ls:(k->ls=new segenode)),l,(l+r)/2);
else edi((k->rs?k->rs:(k->rs=new segenode)),(l+r)/2+1,r);
k->v=max((k->ls?k->ls->v:0),(k->rs?k->rs->v:0));
}
long long gs(segenode *k,const int l,const int r) {
if (tmp1>r||tmp2<l) return 0;
if (tmp1<=l&&r<=tmp2) return k->v;
return max((k->ls?gs(k->ls,l,(l+r)/2):0),
(k->rs?gs(k->rs,(l+r)/2+1,r):0));
}
segetree(const int l=0,const int r=0):l(l),r(r) {}
inline void edi(const int p,const long long v) {
tmp1=p,tmp3=v; edi(&Root,l,r);
}
inline long long gs(const int ql,const int qr) {
tmp1=ql,tmp2=qr; return gs(&Root,l,r);
}
} s(1,1e9);
int n,m,k;
long long ans;
pair<int,pair<int,int> > p[100050];
int main() {
scanf("%d%d%d",&n,&m,&k);
for (int i=0; i<k; ++i) scanf("%d%d%d",&p[i].first,
&p[i].second.first,&p[i].second.second);
sort(p,p+k);
for (int i=0; i<k; ++i) {
long long res=s.gs(1,p[i].second.first)+p[i].second.second;
s.edi(p[i].second.first,res); ans=max(ans,res);
}
cout<<ans;
}