傳送門
題解:
容易想到首先要求一個LIS。
根據以其結尾的LIS長度,把點分爲若干集合,設爲 ,容易注意到一個集合中橫座標增加的同時縱座標減小。
容易得到一個顯然的DP:
發現權值的圖像好像是反比例函數,考慮什麼時候決策 比決策 優秀。
發現決策的分界線是一條斜率爲正的直線,一個半平面會選擇 另一個會選擇 。
但是我們顯然是不能把所有半平面算出來求半平面交的。
但是我們知道如果對於某個點決策 比決策 優秀,則這個點左邊/右邊的所有點決策 都比決策 優秀。
於是可以分治下去找到最優決策,注意DP對座標有要求,結合線段樹進行分治即可。
分治套分治,複雜度兩個log。
代碼:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
namespace IO{
inline char gc(){
static cs int Rlen=1<<22|1;static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}template<typename T>T get_integer(){
char c;bool f=false;while(!isdigit(c=gc()))f=c=='-';T x=c^48;
while(isdigit(c=gc()))x=((x+(x<<2))<<1)+(c^48);return f?-x:x;
}inline int gi(){return get_integer<int>();}
}using namespace IO;
using std::cerr;
using std::cout;
cs int N=2e5+7;
int n,T;
int x[N],y[N],id[N];
int lis[N],a[N],mx;
ll calc(int i,int j){
return (ll)(x[i]-x[j])*(y[i]-y[j]);
}
std::vector<int> ps[N];
ll dp[N];
namespace SGT{
std::vector<int> sol[N<<2];
#define lc u<<1
#define rc lc|1
void DP(int ql,int qr,cs std::vector<int> &q,int l,int r,cs std::vector<int> &ps){
int qm=(ql+qr)>>1,qid=q[qm],m=0;ll tmp=1e18;
for(int re i=l;i<=r;++i)
if(tmp>dp[ps[i]]+calc(ps[i],qid))
{tmp=dp[ps[i]]+calc(ps[i],qid),m=i;}
dp[qid]=std::min(dp[qid],tmp);
if(ql<qm)DP(ql,qm-1,q,m,r,ps);
if(qm<qr)DP(qm+1,qr,q,l,m,ps);
}
void ins(int u,int l,int r,int p,cs std::vector<int> &ps){
if(y[ps[l]]<y[p]&&x[ps[r]]<x[p])
return sol[u].push_back(p);
if(y[ps[r]]>y[p]||x[ps[l]]>x[p])
return ;int m=(l+r)>>1;
ins(lc,l,m,p,ps);ins(rc,m+1,r,p,ps);
}
void solve(int u,int l,int r,cs std::vector<int> &ps){
if(sol[u].size())DP(0,sol[u].size()-1,sol[u],l,r,ps);
sol[u].clear();if(l==r)return ;int m=(l+r)>>1;
solve(lc,l,m,ps);solve(rc,m+1,r,ps);
}
}
void Main(){
n=gi(),T=gi();
for(int re i=1;i<=n;++i)
x[i]=gi(),y[i]=gi(),id[i]=i;
std::sort(id+1,id+n+1,
[](int i,int j){return x[i]<x[j];});mx=0;
for(int re i=1;i<=n;++i){
int j=id[i];
if(y[j]>=a[mx]){
lis[j]=++mx;
a[mx]=y[j];
}else {
lis[j]=std::upper_bound(a+1,a+mx+1,y[j])-a;
a[lis[j]]=y[j];
}ps[lis[j]].push_back(j);
}std::fill(dp+1,dp+n+1,1e18);
for(int i:ps[1])dp[i]=(ll)x[i]*y[i];
for(int re i=2;i<=mx;++i){
for(int j:ps[i])
SGT::ins(1,0,ps[i-1].size()-1,j,ps[i-1]);
SGT::solve(1,0,ps[i-1].size()-1,ps[i-1]);
}ll ans=1e18;
for(int i:ps[mx])
ans=std::min(ans,dp[i]+(ll)(T-x[i])*(T-y[i]));
cout<<ans<<"\n";
}
inline void file(){
#ifdef zxyoi
freopen("mischief.in","r",stdin);
#endif
}signed main(){file();Main();return 0;}