题意:给你一个矩阵,只能从左下走到右上,有一些点有权值,求最大权值,n,m<=1e9,点数<=1e5.
这模型见过不止一次了,最近一次应该是agc19吧,这种明显就二维偏序啊,cdq或者带权lis都可以。
懒得写cdq,写了个带权的lis,具体来说就是做第二维的lis,然后取个最大值,注意所有长度的lis都要算一下,因为带上了权值以后不保证最长就是最大,然后用bit优化一波了,二分会炸。
其实具体来说不能算lis,只不过思想差不多而已。
由于矩阵大,所以离散一波。
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
int n,m;
const int N=1e5+5;
int f[N],t[N],k,tot,mx;
struct nod
{
int v,id;
}hash[N];
struct node
{
int x,y,z;
}a[N];
bool cmp(nod a,nod b)
{
return a.v<b.v;
}
bool cmp1(node a,node b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline void add(int x,int y)
{
while(x<=tot)
{
t[x]=max(t[x],y);
x+=x&-x;
}
}
inline int find(int x)
{
int ret=0;
while (x>0)
{
ret=max(ret,t[x]);
x-=x&-x;
}
return ret;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
fo(i,1,k)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
hash[i].id=i,hash[i].v=a[i].y;
}
sort(hash+1,hash+k+1,cmp);
hash[0].v=-1;
fo(i,1,k)
{
if (hash[i].v!=hash[i-1].v)tot++;
a[hash[i].id].y=tot;
}
sort(a+1,a+1+k,cmp1);
fo(i,1,k)
{
f[i]=a[i].z+find(a[i].y);
add(a[i].y,f[i]);
mx=max(mx,f[i]);
}
printf("%d\n",mx);
}