http://poj.org/problem?id=3277
经典的矩形面积并 对y离散后 建树 用拆点后的以x为顺序 依次更新
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<cstring>
#include<set>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
const int N=40005;
struct node
{
int l,r;
LL H;//这个高度主要是用来查找的
LL h;//这一段的最高度
int cover;//被覆盖次数
}mem[N*4];
LL Y[N*2];//高度
struct poin
{
int k;
LL x;
LL h;
}point[N*2];//拆点 k 表示左点 还是右点
bool cmp(poin a,poin b)
{
if(a.x==b.x)
return a.h<b.h;
return a.x<b.x;
}
LL Labs(LL x)
{
if(x<0)
return -x;
return x;
}
LL Lmax(LL x,LL y)
{
if(x>y)
return x;
return y;
}
void build(int x,int l,int r)
{
mem[x].cover=0;
mem[x].l=l;
mem[x].r=r;
mem[x].h=0;
if(l==r)
{
mem[x].H=Y[l];
return ;
}
int mid=(l+r)>>1;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
mem[x].H=Lmax(mem[x*2].H,mem[x*2+1].H);//更新最高度
}
void add(int x,int k)
{
if(mem[x].l==mem[x].r)
{
mem[x].cover+=point[k].k;//更新cover
if(mem[x].cover>0)//大于0 为有覆盖 所以高度为 H 否则为0
mem[x].h=mem[x].H;
else
mem[x].h=0;
return ;
}
if(Labs(point[k].h)<=mem[x*2].H)
add(x*2,k);
else
add(x*2+1,k);
mem[x].h=Lmax(mem[x*2].h,mem[x*2+1].h);//更新
}
int main()
{
// freopen("data.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;++i)
{
scanf("%I64d %I64d %I64d",&point[i].x,&point[i+n].x,&point[i].h);
point[i+n].h=point[i].h;
point[i].k=1;
point[i+n].k=-1;
Y[i]=point[i].h;
}
sort(Y,Y+n);
sort(point,point+n*2,cmp);
build(1,0,n-1);//对排序后的高度进行建树
add(1,0);
LL ans=0;
for(int i=1;i<2*n;++i)
{
ans+=(point[i].x-point[i-1].x)*mem[1].h;//更新面积
add(1,i);
}
cout<<ans<<endl;
}
return 0;
}
浙公网安备 33010602011771号