如果坐标范围小一点就是最普通dp
范围大了 离散化一下
再加上树状数组维护一个前缀的最大值
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<iostream>
#define lowbit(x) (x&(-x))
#define T 110005
using namespace std;
int sc()
{
int i=0; char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i;
}
struct W{int x,y,v;}a[T];
int b[T*2],h[T*2],tr[T*2];
int tot,cnt,n,m,K;
bool cmp(W a,W b){return a.x==b.x?a.y<b.y:a.x<b.x;}
int search(int x)
{
int l=1,r=cnt;
while(l!=r)
{
int mid=l+r>>1;
if(h[mid]==x)return mid;
else if(h[mid]>x)r=mid-1;
else l=mid+1;
}
return l;
}
int ask(int x)
{
int ans=0;
for(;x;x-=lowbit(x))ans=max(ans,tr[x]);
return ans;
}
void updata(int x,int f)
{
for(;x<=cnt;x+=lowbit(x))tr[x]=max(tr[x],f);
}
int main()
{
n=sc(),m=sc(),K=sc();
for(int i=1;i<=K;i++)
{
b[++tot]=a[i].x=sc();
b[++tot]=a[i].y=sc();
a[i].v=sc();
}
b[++tot]=1;
b[++tot]=n;
b[++tot]=m;
sort(b+1,b+tot+1);
for(int i=1;i<=tot;i++)
if(b[i]!=b[i-1])
h[++cnt]=b[i];
sort(a+1,a+K+1,cmp);
for(int i=1;i<=K;i++)
{
int pos=search(a[i].y);
int mx=ask(pos)+a[i].v;
updata(pos,mx);
}
cout<<ask(search(m));
return 0;
}