## 题意

$$n\le 1\times 10^5$$.

## 题解

$dp_i=\max_{j<i} \begin{cases} dp_j+w_i &(r_j<l_i)\\ dp_j-(r_j-l_i)^2+w_i &(r_j\ge l_i) \end{cases}$

\begin{aligned} dp_i&=\max_{j<i,r_j\ge l_i} \{dp_j-(r_j-l_i)^2+w_i\}\\ &=\max_{j<i,r_j\ge l_i}\{dp_j-r_j^2+2r_jl_i-l_i^2+w_i\}\\ &=\max_{j<i,r_j\ge l_i}\{dp_j-r_j^2+2r_jl_i\}-l_i^2+w_i \end{aligned}

### 参考代码

#include <bits/stdc++.h>

const int MAXN=1e5+10;
typedef long long intEx;

struct Point{
int l;
int r;
intEx w;
};
Point P[MAXN];

int n;
int s[MAXN];
intEx smax[MAXN];

struct Line{
intEx k;
intEx b;
Line(const intEx& a,const intEx& b):k(a),b(b){}
inline intEx operator()(const int& x)const{
return k*s[x]+b;
}
};

struct Node{
int l;
int r;
Line f;
Node* lch;
Node* rch;
~Node();
Node(int,int);
intEx Query(int);
void Insert(Line);
};

int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
P[i].l=x-y;
P[i].r=x+y;
s[i]=P[i].l;
P[i].w=4ll*y*y-4ll*c*y;
}
std::sort(P+1,P+n+1,
[](const Point& a,const Point& b){
return a.r<b.r;
}
);
std::sort(s+1,s+n+1);
int cnt=std::unique(s+1,s+n+1)-s-1;
Node* N=new Node(1,cnt);
for(int i=1;i<=n;i++){
//			printf("[%d,%d] w=%lld\n",P[i].l,P[i].r,P[i].w);
int h=std::lower_bound(s+1,s+cnt+1,P[i].l)-s;

intEx dp=N->Query(h)-1ll*P[i].l*P[i].l+P[i].w;

int p=std::lower_bound(P+1,P+n+1,P[i].l,
[](const Point& a,const int& b){
return a.r<b;
}
)-P-1;
dp=std::max(smax[p]+P[i].w,dp);

N->Insert(Line(2*P[i].r,dp-1ll*P[i].r*P[i].r));
smax[i]=std::max(smax[i-1],dp);
}
printf("%lld.%02lld\n",smax[n]>>2,(smax[n]&3)*25);
delete N;
}
return 0;
}

intEx Node::Query(int x){
if(this->l==this->r)
return this->f(x);
else{
if(x<=this->lch->r)
return std::max(this->lch->Query(x),this->f(x));
else
return std::max(this->rch->Query(x),this->f(x));
}
}

void Node::Insert(Line f){
int mid=(this->l+this->r)>>1;
if(f(mid)>this->f(mid))
std::swap(f,this->f);
intEx ld=this->f(this->l)-f(this->l);
intEx rd=this->f(this->r)-f(this->r);
if(ld>=0&&rd>=0)
return;
else if(rd>=0)
this->lch->Insert(f);
else
this->rch->Insert(f);
}

Node::~Node(){
if(this->lch)
delete this->lch;
if(this->rch)
delete this->rch;
}

Node::Node(int l,int r):l(l),r(r),f(0,-1e18),lch(NULL),rch(NULL){
if(l!=r){
int mid=(l+r)>>1;
this->lch=new Node(l,mid);
this->rch=new Node(mid+1,r);
}
}



posted @ 2019-04-02 10:11  rvalue  阅读(304)  评论(0编辑  收藏  举报