rt,将 0 点一同加入 cdq 分治 dp。但是会 WA。
把 0 点的转移先处理好再 cdq(1,n) 就可以过。why?
出锅的代码
//CDQ
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,lsh,bit[N],f[N];
set<int>s;
map<int,int>mp;
struct node{
int a,b,c,w,id,pos;
}A[N],B[N];
void modify(int x,int k){
for(int i=x;i<=n+1;i+=i&(-i)){
bit[i]=max(bit[i],k);
}
}
int query(int x){
int ret=0;
for(int i=x;i;i-=i&(-i)){
ret=max(ret,bit[i]);
}
return ret;
}
void erase(int x){
for(int i=x;i<=n+1;i+=i&(-i)){
bit[i]=0;
}
}
void cdq(int l,int r){
if(l^r){
int mid=(l+r)>>1ll;
cdq(l,mid);
for(int i=l;i<=r;++i){
B[i]=A[i];
}
sort(B+l,B+r+1,[](node u,node v){return u.b^v.b?u.b<v.b:u.id<v.id;});
for(int i=l;i<=r;++i){
if(B[i].id<=mid){
modify(B[i].c,f[B[i].pos]);
}else{
f[B[i].pos]=max(f[B[i].pos],query(B[i].c)+B[i].w);
}
}
for(int i=l;i<=r;++i){
if(B[i].id<=mid){
erase(B[i].c);
}
}
cdq(mid+1,r);
}
}
signed main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n;
A[0]={0,0,0,0,0,0};
s.insert(0);
for(int i=1,x,y,t,a;i<=n;++i){
cin>>t>>x>>y>>a;
A[i]={y,t-x-y,t+x-y,a,0,i};
s.insert(t+x-y);
}
for(int i:s){
mp[i]=++lsh;
}
for(int i=0;i<=n;++i){
A[i].c=mp[A[i].c];
}
sort(A,A+1+n,[](node u,node v){return u.a^v.a?u.a<v.a:u.b^v.b?u.b<v.b:u.c<v.c;});
for(int i=0;i<=n;++i){
A[i].id=i;
}
cdq(0,n);
cout<<*max_element(f,f+1+n);
}