题目链接
注意这个题是以0结尾的坑了我半天
大佬的博客里面有详解
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e4+10;
double x[maxn];
struct zp
{
double x1,x2,y,flag;
} arr[maxn*4];
bool cmp(zp a,zp b)
{
return a.y<b.y;
}
struct tree
{
int l,r;
double num,lazy;//lazy不是0代表这段区间被覆盖,为0代表没有被覆盖
} node[maxn*4];
void pushup(int k)
{
int l=node[k].l,r=node[k].r; //这里加1
if(node[k].lazy!=0) node[k].num=x[r+1]-x[l];//没有被覆盖则该段区间值为区间所离散化的长度
else if(l==r) node[k].num=0;
else node[k].num=node[k<<1].num+node[k<<1|1].num;//没有被覆盖则是他两个儿子节点的值之和
}
void build_tree(int l,int r,int k)//建树
{
node[k].l=l,node[k].r=r,node[k].lazy=node[k].num=0;
if(l==r)
return ;
int mid=(l+r)>>1;
build_tree(l,mid,k<<1);
build_tree(mid+1,r,k<<1|1);
}
void update(int l,int r,int k,double num)
{
if(node[k].l==l&&node[k].r==r)
{
node[k].lazy+=num;
pushup(k);
return ;
}
int mid=(node[k].l+node[k].r)>>1;
if(r<=mid)
update(l,r,k<<1,num);
else if(l>mid)
update(l,r,k<<1|1,num);
else
update(l,mid,k<<1,num),update(mid+1,r,k<<1|1,num);
pushup(k);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==0)//神坑
break;
build_tree(1,4*n,1);
for(int i=1; i<=n; i++)
{
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
arr[2*i-1].x1=arr[2*i].x1=a;
arr[2*i-1].x2=arr[2*i].x2=c;
arr[2*i-1].y=b,arr[2*i].y=d;
arr[2*i-1].flag=1,arr[2*i].flag=-1;//1代表矩形的下线,-1代表上线,扫过之后就相当于不存在
x[2*i-1]=a,x[2*i]=c;
}
n=2*n;
sort(arr+1,arr+n+1,cmp);
sort(x+1,x+n+1);//离散化坐标点
double ans=0;
for(int i=1;i<=n;i++)
{
int l=lower_bound(x+1,x+n+1,arr[i].x1)-x;
int r=lower_bound(x+1,x+n+1,arr[i].x2)-x-1;//这里减一是为了好处理区间的和对应pushup里的+1
if(l<=r) update(l,r,1,arr[i].flag);
ans+=node[1].num*(arr[i+1].y-arr[i].y);
}
printf("%.2lf\n",ans);
}
}