题意:给定每个矩形的高度以及底边在数轴上的起点和终点。各矩形间可能有重叠。问它们覆盖的总面积是多少。
将横坐标离散化存到线段树中,然后离线算法,从低到高依次更新,后面的直接覆盖前面的即可
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "algorithm"
using namespace std;
struct Mar
{
__int64 l,r,op;
}mark[40010];
struct B
{
__int64 l,r;
}b[100010];
struct node
{
int l,r;
__int64 zuo,you,cover,x;
}data[400010];
bool cmp(Mar a,Mar b)
{
return a.op<b.op;
}
void build(int l,int r,int k)
{
int mid;
data[k].l=l;
data[k].r=r;
data[k].cover=-1;
data[k].x=0;
if (l==r)
{
data[k].zuo=b[l].l;
data[k].you=b[l].r;
return ;
}
mid=(data[k].l+data[k].r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
data[k].zuo=data[k*2].zuo;
data[k].you=data[k*2+1].you;
}
void Pushdown(int k)
{
if (data[k].l==data[k].r) return ;
if (data[k].x==-1) return ;
data[k*2].x=data[k*2+1].x=data[k].x;
data[k].x=-1;
}
void updata(__int64 zuo,__int64 you,int k,__int64 op)
{
if (data[k].x>=op) return ;
if (data[k].zuo==zuo && data[k].you==you)
{
data[k].x=op;
return ;
}
Pushdown(k);
if (data[k*2].you>=you) updata(zuo,you,k*2,op);
else
if (data[k*2+1].zuo<=zuo) updata(zuo,you,k*2+1,op);
else
{
updata(zuo,data[k*2].you,k*2,op);
updata(data[k*2+1].zuo,you,k*2+1,op);
}
if (data[k*2].x==data[k*2+1].x) data[k].x=data[k*2].x;
else data[k].x=-1;
}
__int64 query(int k)
{
if (data[k].x!=-1)
{
return (data[k].you-data[k].zuo)*data[k].x;
}
return query(k*2)+query(k*2+1);
}
int main()
{
int n,sum,last,m,i;
__int64 a[100010];
while (scanf("%d",&n)!=EOF)
{
sum=0;
for (i=1;i<=n;i++)
{
scanf("%I64d%I64d%I64d",&mark[i].l,&mark[i].r,&mark[i].op);
a[sum++]=mark[i].l;
a[sum++]=mark[i].r;
}
sort(a,a+sum);
last=a[0];
m=0;
for (i=1;i<sum;i++)
{
if (a[i]!=a[i-1])
{
m++;
b[m].l=last;
b[m].r=a[i];
last=a[i];
}
}
sort(mark+1,mark+n+1,cmp);
build(1,m,1);
for (i=1;i<=n;i++)
updata(mark[i].l,mark[i].r,1,mark[i].op);
printf("%I64d\n",query(1));
}
return 0;
}