第二种更好理解点。
以前虽然学过离散化,但是接触的只是皮毛而已。
这道题就不会了。于是深深理解了下kuangbin的code。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct Node{
int x,y,v;
void input(){
scanf("%d%d%d",&x,&y,&v);
}
}node[maxn];
bool cmp(Node a,Node b){
return a.x<b.x;
}
int a[maxn];
int c[maxn];
int tot;
int lowbit(int x){
return x&(-x);
}
void update(int i,int val){
while(i<=tot){
c[i]=max(c[i],val);
i+=lowbit(i);
}
}
int query(int i){
int res=0;
while(i>0){
res=max(res,c[i]);
i-=lowbit(i);
}
return res;
}
int dp[maxn];
int main(){
int T;
int n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++){
node[i].input();
}
tot=0;
for(int i=0;i<n;i++){
a[tot++]=node[i].y;
}
sort(a,a+tot);
tot=unique(a,a+tot)-a;
for(int i=0;i<n;i++){
node[i].y=lower_bound(a,a+tot,node[i].y)-a+1;
}
sort(node,node+n,cmp);
for(int i=0;i<n;i++){
dp[i]=node[i].v;
}
for(int i=1;i<=tot;i++){
c[i]=0;
}
int pos=0;
int ans=0;
for(int i=0;i<n;i++){
while(pos<i&&node[pos].x<node[i].x){
update(node[pos].y,dp[pos]);
pos++;
}
dp[i]=query(node[i].y-1)+node[i].v;
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
}
树状数组维护最值:
(数据有问题,不用离散化直接就可以树状数组维护,其实离散化下更好。)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct Node{
int x,y,v;
inline void input(){
scanf("%d%d%d",&x,&y,&v);
}
}node[maxn];
bool cmp(Node a,Node b){
if(a.x!=b.x)
return a.x<b.x;
else return a.y>b.y;
}
int c[maxn];
int lowbit(int x){
return x&(-x);
}
void update(int i,int val){
while(i<maxn){
c[i]=max(c[i],val);
i+=lowbit(i);
}
}
int query(int i){
int res=0;
while(i>0){
res=max(res,c[i]);
i-=lowbit(i);
}
return res;
}
int dp[maxn];
int main(){
int T;
int n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++){
node[i].input();
}
sort(node,node+n,cmp);
memset(c,00,sizeof(c));
int ans=0;
for(int i=0;i<n;i++){
update(node[i].y,query(node[i].y-1)+node[i].v);
}
printf("%d\n",query(n));
}
}