2018徐州网络赛G

给n个以原点为左下角的矩形,求最后图形右边界和上边界的周长和。

从后向前放矩形,线段树维护每个点左边最近的距离及下面最近的距离即可。

 

 

 

#include <bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define up rt,rt<<1,rt<<1|1
#define mem(x) memset(x,0,sizeof(x))
#define mem1(x) memset(x,-1,sizeof(x))
using namespace std;
typedef long long ll;
typedef double db;
const int M = 5e4+7;

int n,x[M],y[M],xx[M],yy[M];
int mxx[M<<2],mxy[M<<2],lazx[M<<2],lazy[M<<2];
int posx,posy;
ll ans=0;
void pushdownx(int rt,int l,int r){
    if(lazx[rt]){
        int v=lazx[rt];
        lazx[rt]=0;
        lazx[l]=v;mxx[l]=v;
        lazx[r]=v;mxx[r]=v;
    }
}
void pushdowny(int rt,int l,int r){
    if(lazy[rt]){
        int v=lazy[rt];
        lazy[rt]=0;
        lazy[l]=v;mxy[l]=v;
        lazy[r]=v;mxy[r]=v;
    }
}
void buildx(int l,int r,int rt){
    mxx[rt]=0;
    if(l==r) return ;
    int mid=(l+r)>>1;
    buildx(lson);
    buildx(rson);
}
void buildy(int l,int r,int rt){
    mxy[rt]=0;
    if(l==r) return ;
    int mid=(l+r)>>1;
    buildy(lson);
    buildy(rson);
}
void updatex(int L,int R,int l,int r,int rt,int v){
    if(L<=l&&r<=R){
        lazx[rt]=v;mxx[rt]=v;
        return ;
    }
    pushdownx(up);
    int mid=(l+r)>>1;
    if(L<=mid) updatex(L,R,lson,v);
    if(R>mid) updatex(L,R,rson,v);
}
void updatey(int L,int R,int l,int r,int rt,int v){
    if(L<=l&&r<=R){
        lazy[rt]=v;mxy[rt]=v;
        return ;
    }
    pushdowny(up);
    int mid=(l+r)>>1;
    if(L<=mid) updatey(L,R,lson,v);
    if(R>mid) updatey(L,R,rson,v);
}
int queryx(int l,int r,int rt){
    if(l==r){
        return mxx[rt];
    }
    pushdownx(up);
    int mid=(l+r)>>1;
    if(posx<=mid) return queryx(lson);
    else return queryx(rson);
}
int queryy(int l,int r,int rt){
    if(l==r){
        return mxy[rt];
    }
    pushdowny(up);
    int mid=(l+r)>>1;
    if(posy<=mid) return queryy(lson);
    else return queryy(rson);
}
void solve(){
    for(int i=n;i>=1;i--){
        posx=lower_bound(xx+1,xx+n+1,x[i])-xx,posy=lower_bound(yy+1,yy+n+1,y[i])-yy;
        int fix=queryx(1,n,1),fiy=queryy(1,n,1);
        //printf("%d %d %d %d\n",x[i],fiy,y[i],fix);
        ans+=1ll*(y[i]-fix+x[i]-fiy);
        int posfix,posfiy;
        if(fix==0) posfiy=1;
        else posfiy=lower_bound(yy+1,yy+n+1,fix)-yy;
        if(fiy==0) posfix=1;
        else posfix=lower_bound(xx+1,xx+n+1,fiy)-xx;
        updatex(posfix,posx,1,n,1,y[i]);
        updatey(posfiy,posy,1,n,1,x[i]);
    }
}
int main(){
    #ifdef LMissher
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]),xx[i]=x[i],yy[i]=y[i];
    sort(xx+1,xx+n+1);sort(yy+1,yy+n+1);
    buildx(1,n,1);
    buildy(1,n,1);
    solve();
    printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2018-09-09 21:58  LMissher  阅读(220)  评论(0)    收藏  举报