【线段树+扫描线】&矩形覆盖求面积/周长问题(POJ - 1151 /HDU 1828)

poj 1151

#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf  0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 5005
#define M 4000009

#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);
using namespace std;
typedef long long  ll;
typedef double db;
const ll mod=1e9+7;
double sum[N],a[N];
int f[N];
struct node
{
    double lx,rx,y;
    int flag;
    node(){}
    node(double a,double b,double c,double d)
    {
        lx=a,rx=b,y=c,flag=d;
    }
    bool operator<(const node b) const
    {
        return y<b.y;
    }
}line[N];
int findx(double x,int n)
{
    return lower_bound(a+1,a+1+n,x)-a;
}
void push_up(int u,int l,int r)
{
    if(f[u]) sum[u]=a[r+1]-a[l];
    else if(l==r) sum[u]=0;
    else sum[u]=sum[u<<1]+sum[u<<1|1];
}
void update(int u,int l,int r,int tl,int tr,int x)
{
    if(tr<l||tl>r) return ;
    if(tl<=l&&r<=tr)
    {
        f[u]+=x;
        push_up(u,l,r);
        return ;
    }
    int mid=(l+r)>>1;
    update(u<<1,l,mid,tl,tr,x);
    update(u<<1|1,mid+1,r,tl,tr,x);
    push_up(u,l,r);
}
int main()
{
    int n,m,t=1;
    while(~sd(m)&&m)
    {
        int num=0;
        mem(f,0);
        mem(sum,0);
        n=0;
        fup(i,1,m)
        {
            double x1,x2,y1,y2;
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            line[++n]=node(x1,x2,y1,1);
            a[n]=x1;
            line[++n]=node(x1,x2,y2,-1);
            a[n]=x2;
        };
        sort(a+1,a+1+n);
        sort(line+1,line+1+n);
        int len=1;
        for(int i=2; i<=n; i++)
            if(a[i]!=a[i+1]) a[++len]=a[i];
    //    cout<<len<<' '<<n<<endl;
        double ans=0;
        fup(i,1,n-1)
        {
            int l=findx(line[i].lx,len);
            int r=findx(line[i].rx,len)-1;
            update(1,1,len,l,r,line[i].flag);
          //  cout<<l<<' '<<line[i].y<<endl;
            ans+=sum[1]*(line[i+1].y-line[i].y);
        }
        printf("Test case #%d\n",t++);
        printf("Total explored area: %.2lf\n\n",ans);
    }
}

HDU 1828

hdu 1828

详细介绍

方法1

#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf  0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 50005
#define M 4000009

#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);
using namespace std;
typedef long long  ll;
typedef double db;
const ll mod=1e9+7;
double a[N];
int b[N][4];
struct tre
{
    int len;///这个区间被覆盖的长度
    int f;///表示这个区间被重复覆盖了几次
}t[N];
struct node
{
    double lx,rx,y;
    int flag;
    node(){}
    node(double a,double b,double c,double d)
    {
        lx=a,rx=b,y=c,flag=d;
    }
    bool operator<(const node b) const
    {
        return y<b.y;
    }
}line[N];
int findx(double x,int n)
{
    return lower_bound(a+1,a+1+n,x)-a;
}
void push_up(int u,int l,int r)
{
    if(t[u].f) t[u].len=a[r+1]-a[l];
    else if(l==r) t[u].len=0;
    else t[u].len=t[u<<1].len+t[u<<1|1].len;
}
void update(int u,int l,int r,int tl,int tr,int x)
{
    if(tr<l||tl>r) return ;
    if(tl<=l&&r<=tr)
    {
        t[u].f+=x;
        push_up(u,l,r);
        return ;
    }
    int mid=(l+r)>>1;
    update(u<<1,l,mid,tl,tr,x);
    update(u<<1|1,mid+1,r,tl,tr,x);
    push_up(u,l,r);
}
int main()
{
    int n,m;
    while(~sd(m)&&m)
    {
        double ans=0,last=0;
        mem(t,0);
        n=0;
        fup(i,1,m)
        {
            double x1,x2,y1,y2;
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            b[i][0]=x1,b[i][1]=y1,b[i][2]=x2,b[i][3]=y2;
            line[++n]=node(x1,x2,y1,1);
            a[n]=x1;
            line[++n]=node(x1,x2,y2,-1);
            a[n]=x2;
        };
        sort(a+1,a+1+n);
        sort(line+1,line+1+n);
        int len=1;
        for(int i=2; i<=n; i++)
            if(a[i]!=a[i+1]) a[++len]=a[i];
        fup(i,1,n)
        {
            int l=findx(line[i].lx,len);
            int r=findx(line[i].rx,len)-1;
            update(1,1,len,l,r,line[i].flag);
            ans+=fabs(t[1].len-last);
            last=t[1].len;
        }
        ///----------------------------------------
        mem(t,0);
        n=0;
        fup(i,1,m)
        {
            line[++n]=node(b[i][1],b[i][3],b[i][0],1);
            a[n]=b[i][1];
            line[++n]=node(b[i][1],b[i][3],b[i][2],-1);
            a[n]=b[i][3];
        };
        sort(a+1,a+1+n);
        sort(line+1,line+1+n);
        len=1;
        for(int i=2; i<=n; i++)
            if(a[i]!=a[i+1]) a[++len]=a[i];
        fup(i,1,n)
        {
            int l=findx(line[i].lx,len);
            int r=findx(line[i].rx,len)-1;
            update(1,1,len,l,r,line[i].flag);
            ans+=fabs(t[1].len-last);
            last=t[1].len;
        }
        printf("%.0lf\n",ans);
    }
}

方法2

#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf  0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 50005
#define M 4000009

#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);
using namespace std;
typedef long long  ll;
typedef double db;
const ll mod=1e9+7;
double a[N];
struct tre
{
    int len;///这个区间被覆盖的长度
    int f;///表示这个区间被重复覆盖了几次
    int lc,rc;///表示这个节点左右两个端点是否被覆盖(0表示没有被覆盖,1表示有被覆盖)
    int num;///这个区间有多少条线段(这个区间被多少条线段覆盖)
    ///len用来计算横线 num用来计算竖线
}t[N];
struct node
{
    double lx,rx,y;
    int flag;
    node(){}
    node(double a,double b,double c,double d)
    {
        lx=a,rx=b,y=c,flag=d;
    }
    bool operator<(const node b) const
    {
        return y<b.y;
    }
}line[N];
int findx(double x,int n)
{
    return lower_bound(a+1,a+1+n,x)-a;
}
void push_up(int u,int l,int r)
{
    if(t[u].f)
    {
        t[u].len=a[r+1]-a[l];
        t[u].lc=t[u].rc=t[u].num=1;
    }
    else if(l==r)
    {
        t[u].lc=t[u].rc=t[u].num=t[u].len=0;
    }
    else
    {
        t[u].len=t[u<<1].len+t[u<<1|1].len;
        t[u].lc=t[u<<1].lc;
        t[u].rc=t[u<<1|1].rc;
        t[u].num=t[u<<1].num+t[u<<1|1].num-(t[u<<1].rc&t[u<<1|1].lc);
    }
}
void update(int u,int l,int r,int tl,int tr,int x)
{
    if(tr<l||tl>r) return ;
    if(tl<=l&&r<=tr)
    {
        t[u].f+=x;
        push_up(u,l,r);
        return ;
    }
    int mid=(l+r)>>1;
    update(u<<1,l,mid,tl,tr,x);
    update(u<<1|1,mid+1,r,tl,tr,x);
    push_up(u,l,r);
}
int main()
{
    int n,m;
    while(~sd(m)&&m)
    {
        mem(t,0);
        n=0;
        fup(i,1,m)
        {
            double x1,x2,y1,y2;
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            line[++n]=node(x1,x2,y1,1);
            a[n]=x1;
            line[++n]=node(x1,x2,y2,-1);
            a[n]=x2;
        };
        sort(a+1,a+1+n);
        sort(line+1,line+1+n);
        int len=1;
        for(int i=2; i<=n; i++)
            if(a[i]!=a[i+1]) a[++len]=a[i];
   //     cout<<len<<' '<<n<<endl;
        double ans=0,last=0;
        fup(i,1,n)
        {
            int l=findx(line[i].lx,len);
            int r=findx(line[i].rx,len)-1;
            update(1,1,len,l,r,line[i].flag);
          //  cout<<l<<' '<<line[i].y<<endl;
            ans+=fabs(t[1].len-last);
            ans+=(line[i+1].y-line[i].y)*t[1].num*2;
            last=t[1].len;
          //  cout<<ans<<endl;
        }
        printf("%.0lf\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_25973789/article/details/81033252