UVA1492 LA5694 线段树扫描线(矩形面积合并)

来源:互联网 发布:苹果mac好用吗 编辑:程序博客网 时间:2024/04/30 09:51
我们考虑 每个新机器往右放的起始点(1*1的块)那么我们只要求出哪些位置不可以放就可以了,比如说 3*3 的矩阵 新机器长为2  旧机器在2 2 那么 1 1这个点就不可以放新机器(考虑机器往右放的起始点)再考虑右边界,右边界左边m-1个位置也不可以放再考虑往下放的起始点,同理了综上我们只要分别求出 哪些点不可以放 再用所有点减去就可以了其实这就转化成了求矩形面积合并的问题了注意特判m=1 横着放竖着放重复计算了线段树实现矩形面积合并时还是要注意一些细节,每个节点储存的是这个点到右边那个点的距离
#include <bits/stdc++.h>using namespace std;const int maxn=2e5+10;typedef long long ll;ll w,h,n,m;struct data{    ll x1,x2,y;    int flag;} a[maxn<<2],b[maxn<<2];ll hasha[maxn],hashb[maxn];ll sum[maxn<<2];ll col[maxn<<2],flaga[maxn],flagb[maxn];inline bool cmp(data a,data b){    return a.y<b.y;}void pushup(ll s,ll l,ll r){    if(col[s]) sum[s]=hasha[r+1]-hasha[l];    else if(l==r) sum[s]=0;    else    {        sum[s]=sum[s*2]+sum[s*2+1];    }}void update(ll L,ll R,ll l,ll r,ll flag,ll s){    if(L<=l&&R>=r)    {        col[s]+=flag;        pushup(s,l,r);        return ;    }    ll m=(l+r)/2;    if(L<=m)    {        update(L,R,l,m,flag,s*2);    }    if(R>m)    {        update(L,R,m+1,r,flag,s*2+1);    }    pushup(s,l,r);}int main(){    while(~scanf("%lld%lld%lld%lld",&w,&h,&n,&m))    {        for(int i = 1; i <= n; ++i)        {            ll xx1,yy1,xx2,yy2;            scanf("%lld%lld%lld%lld",&xx1,&yy1,&xx2,&yy2);            a[i*2].x1=a[i*2-1].x1=xx1-m+1>0?xx1-m+1:1;            a[i*2].x2=a[i*2-1].x2=xx2+1;            a[i*2-1].flag=1;            a[i*2].flag=-1;            hasha[i*2-1]=a[i*2-1].x1;            hasha[2*i]=a[i*2].x2;            a[i*2-1].y=yy1;            a[i*2].y=yy2+1;            b[i*2].x1=b[i*2-1].x1=yy1-m+1>0?yy1-m+1:1;            b[i*2].x2=b[i*2-1].x2=yy2+1;            b[i*2-1].y=xx1;            b[i*2].y=xx2+1;            hashb[i*2-1]=b[i*2-1].x1;            hashb[2*i]=b[i*2].x2;            b[i*2-1].flag=1;            b[i*2].flag=-1;        }        memset(col,0,sizeof col);        memset(sum,0,sizeof sum);        a[2*n+2].x1=a[2*n+1].x1=w-m+2>0?w-m+2:1;        a[2*n+1].flag=1;        a[2*n+2].flag=-1;        a[2*n+2].x2=a[2*n+1].x2=w+1;        a[2*n+1].y=1;        a[2*n+2].y=h+1;        hasha[2*n+1]=a[n*2+1].x1;        hasha[2*n+2]=a[n*2+2].x2;        sort(a+1,a+2*n+3,cmp);        sort(hasha+1,hasha+2*n+3);        ll sz=unique(hasha+1,hasha+2*n+3)-hasha;        long long ans=0;        for(ll i = 1; i <= 2*n+2; ++i)        {            ll l=lower_bound(hasha+1,hasha+sz,a[i].x1)-hasha;            ll r=lower_bound(hasha+1,hasha+sz,a[i].x2)-hasha-1;            if(r>=l) update(l,r,1,sz-1,a[i].flag,1);            ans+=sum[1]*(a[i+1].y-a[i].y);        }        for(ll i = 1; i <= 2*n+2; ++i)        {            hasha[i]=hashb[i];            a[i]=b[i];        }        a[2*n+2].x1=a[2*n+1].x1=h-m+2>0?h-m+2:1;        a[2*n+2].x2=a[2*n+1].x2=h+1;        a[2*n+1].y=1;        a[2*n+2].y=w+1;        a[2*n+1].flag=1;        a[2*n+2].flag=-1;        hasha[2*n+1]=a[n*2+1].x1;        hasha[2*n+2]=a[n*2+2].x2;        memset(col,0,sizeof col);        memset(sum,0,sizeof sum);        sort(a+1,a+2*n+3,cmp);        sort(hasha+1,hasha+2*n+3);        sz=unique(hasha+1,hasha+2*n+3)-hasha;        for(int i = 1; i <= 2*n+2; ++i)        {            ll l=lower_bound(hasha+1,hasha+sz,a[i].x1)-hasha;            ll r=lower_bound(hasha+1,hasha+sz,a[i].x2)-hasha-1;            if(r>=l) update(l,r,1,sz-1,a[i].flag,1);            ans+=sum[1]*(a[i+1].y-a[i].y);        }        ans=(long long)w*h*2-ans;        if(m==1) ans/=2;        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击