0
点赞
收藏
分享

微信扫一扫

Trace 计蒜客

​​https://nanti.jisuanke.com/t/31459​​

逆向考虑 对于每个矩形的右上顶点(xi,yi) 查一下y=yi这条直线上最大的x值 若小于xi 则答案加上这个差值 x=xi亦然

主要是因为逆向考虑有一个等效替代的过程 画图模拟一下即可

#include <bits/stdc++.h>
using namespace std;
#define ll long long

struct node
{
ll x;
ll y;
};

node point[50010];
ll maxx[200010],maxy[200010];
ll tmpx[50010],tmpy[50010];
int n,lenx,leny;

ll getmax(ll x,ll y)
{
if(x>y) return x;
else return y;
}

void queryx(int tar,ll &resx,int l,int r,int cur)
{
int m;
resx=getmax(resx,maxx[cur]);
if(l==r) return;
m=(l+r)/2;
if(tar<=m) queryx(tar,resx,l,m,2*cur);
else queryx(tar,resx,m+1,r,2*cur+1);
}

void queryy(int tar,ll &resy,int l,int r,int cur)
{
int m;
resy=getmax(resy,maxy[cur]);
if(l==r) return;
m=(l+r)/2;
if(tar<=m) queryy(tar,resy,l,m,2*cur);
else queryy(tar,resy,m+1,r,2*cur+1);
}

void updatex(int pl,int pr,ll val,int l,int r,int cur)
{
int m;
if(pl<=l&&r<=pr)
{
maxx[cur]=getmax(maxx[cur],val);
return;
}
m=(l+r)/2;
if(pl<=m) updatex(pl,pr,val,l,m,2*cur);
if(pr>m) updatex(pl,pr,val,m+1,r,2*cur+1);
}

void updatey(int pl,int pr,ll val,int l,int r,int cur)
{
int m;
if(pl<=l&&r<=pr)
{
maxy[cur]=getmax(maxy[cur],val);
return;
}
m=(l+r)/2;
if(pl<=m) updatey(pl,pr,val,l,m,2*cur);
if(pr>m) updatey(pl,pr,val,m+1,r,2*cur+1);
}

int main()
{
ll ans,resx,resy;
int i,p1,p2,l,r;
while(scanf("%d",&n)!=EOF)
{
lenx=0,leny=0;
for(i=1;i<=n;i++)
{
scanf("%lld%lld",&point[i].x,&point[i].y);
tmpx[++lenx]=point[i].x;
tmpy[++leny]=point[i].y;
}
tmpx[++lenx]=0,tmpy[++leny]=0;

sort(tmpx+1,tmpx+lenx+1);
lenx=unique(tmpx+1,tmpx+lenx+1)-tmpx-1;
sort(tmpy+1,tmpy+leny+1);
leny=unique(tmpy+1,tmpy+leny+1)-tmpy-1;
for(i=1;i<=4*lenx;i++) maxx[i]=0;
for(i=1;i<=4*leny;i++) maxy[i]=0;

/*
printf("***%d***\n",lenx);
for(i=1;i<=lenx;i++) printf("%lld ",tmpx[i]);
printf("\n");
printf("***%d***\n",leny);
for(i=1;i<=leny;i++) printf("%lld ",tmpy[i]);
printf("\n");
*/

ans=0;
for(i=n;i>=1;i--)
{
p1=lower_bound(tmpx+1,tmpx+lenx+1,point[i].x)-tmpx;
resy=0;
queryx(p1,resy,1,lenx,1);

p2=lower_bound(tmpy+1,tmpy+leny+1,point[i].y)-tmpy;
resx=0;
queryy(p2,resx,1,leny,1);

if(point[i].x>resx) ans+=(point[i].x-resx);
if(point[i].y>resy) ans+=(point[i].y-resy);
//printf("%lld %lld %lld %lld\n",point[i].x,resx,point[i].y,resy);

updatex(1,p1,point[i].y,1,lenx,1);
updatey(1,p2,point[i].x,1,leny,1);
}
printf("%lld\n",ans);
}
return 0;
}

/*
3
5 1
4 2
3 3
*/

 


举报

相关推荐

0 条评论