Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define gc c=getchar()
- #define r(x) read(x)
- #define ll long long
- template<typename T>
- inline void read(T&x){
- x=0;T k=1;char gc;
- while(!isdigit(c)){if(c=='-')k=-1;gc;}
- while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
- }
- const int N=2e5+7;
- const int V=1e6+7;
- const ll INF=1e18;
- struct Point{
- int x,y;
- inline bool operator <(const Point &a)const{
- return x==a.x?y<a.y:x<a.x;
- }
- }P[N];
- int c[V];
- inline void Add(int x,int v){
- for(int i=x;i<V;i+=(i&-i)){
- c[i]=max(c[i],v);
- }
- }
- inline int Max(int x){
- int ret=0;
- for(int i=x;i;i^=(i&-i)){
- ret=max(ret,c[i]);
- }
- return ret;
- }
- #define ls (rt<<1)
- #define rs (rt<<1|1)
- vector<int>Q[N<<2];
- void build(int rt,int l,int r){
- Q[rt].clear();
- if(l==r)return ;
- int mid=(l+r)>>1;
- build(ls,l,mid);
- build(rs,mid+1,r);
- }
- void insert(int rt,int l,int r,int x,int y,int v){
- if(x<=l&&r<=y){
- Q[rt].push_back(v);
- return ;
- }
- int mid=(l+r)>>1;
- if(x<=mid)insert(ls,l,mid,x,y,v);
- if(y>mid)insert(rs,mid+1,r,x,y,v);
- }
- vector<int>group[N];
- vector<ll>dp[N];
- void solve(vector<int>&T,int l,int r,int x,int y,int id){
- if(l>r)return ;
- int mid=(l+r)>>1;
- ll ret=INF;
- int pos;
- Point A=P[group[id][T[mid]]];
- for(int i=x;i<=y;++i){
- Point B=P[group[id-1][i]];
- ll tmp=dp[id-1][i]+(ll)(A.x-B.x)*(A.y-B.y);
- if(ret>tmp)ret=tmp,pos=i;
- }
- dp[id][T[mid]]=min(dp[id][T[mid]],ret);
- solve(T,l,mid-1,pos,y,id);
- solve(T,mid+1,r,x,pos,id);
- }
- void dfs(int rt,int l,int r,int id){
- solve(Q[rt],0,Q[rt].size()-1,l,r,id);
- if(l==r)return;
- int mid=(l+r)>>1;
- dfs(ls,l,mid,id);
- dfs(rs,mid+1,r,id);
- }
- int f[N];
- int main(){
- // freopen(".in","r",stdin);
- // freopen(".out","w",stdout);
- int n,T;r(n),r(T);
- for(int i=1;i<=n;++i){
- r(P[i].x),r(P[i].y);
- }
- sort(P+1,P+n+1);
- ++n;
- P[n].x=T;
- P[n].y=T;
- group[0].push_back(0);
- dp[0].push_back(0);
- for(int i=1;i<=n;++i){
- f[i]=Max(P[i].y)+1;
- group[f[i]].push_back(i);
- Add(P[i].y,f[i]);
- }
- for(int i=1;i<=f[n];++i){
- int m=group[i-1].size()-1;
- build(1,0,m);
- for(int j=0,l,r,mid,ans;j<group[i].size();++j){
- dp[i].push_back(INF);
- Point &A=P[group[i][j]];
- l=0,r=m;
- while(l<=r){
- mid=(l+r)>>1;
- if(P[group[i-1][mid]].y<=A.y)r=mid-1,ans=mid;
- else l=mid+1;
- }
- int st=ans;
- l=0,r=m;
- while(l<=r){
- mid=(l+r)>>1;
- if(P[group[i-1][mid]].x<=A.x)l=mid+1,ans=mid;
- else r=mid-1;
- }
- int ed=ans;
- insert(1,0,m,st,ed,j);
- }
- dfs(1,0,m,i);
- }
- printf("%lld\n",dp[f[n]][0]);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement