先把坐标离散化,然后进行线段树区域更新。
更新的时候应该注意先更新矮的,然后让高的覆盖矮的。
时间复杂度为O(n*log(n))
注意long long
注意线段树的空间长度应该开为maxn*2*4
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<iostream>
#include<stdio.h>
#include<vector>
#define INF 1000000
#define LL long long
#define maxn 80200
using namespace std;
struct list
{
int l;
int r;
int h;
}node[maxn*4+10];
struct lose
{
int x;
int y;
int h;
bool friend operator < (const lose a, const lose b)
{
return a.h<b.h;
}
}build[maxn];
int xx[maxn*3];
int xnum;
int xun(int x)
{
int l=0;
int r=xnum;
int mid=(l+r)/2;
while(l<r)
{
if(xx[mid]==x)break;
if(xx[mid]>x)r=mid;
if(xx[mid]<x)l=mid+1;
mid=(l+r)/2;
}
return mid;
}
void creat(int l,int r,int h,int num)
{
node[num].l=l;
node[num].r=r;
if(l==r)
{
node[num].h=h;
return ;
}
int mid=(l+r)/2;
creat(l,mid,h,num*2+1);
creat(mid+1,r,h,num*2+2);
}
void insert(int l,int r,int h,int num)
{
int a=node[num].l;
int b=node[num].r;
if(l==a&&r==b)
{
node[num].h=h;
return ;
}
int mid=(a+b)/2;
if(node[num].h!=0)
{
node[num*2+1].h=node[num].h;
node[num*2+2].h=node[num].h;
node[num].h=0;
}
if(l>mid )insert(l,r,h,num*2+2);
else if(r<=mid)insert(l,r,h,num*2+1);
else
{
insert(l,mid,h,num*2+1);
insert(mid+1,r,h,num*2+2);
}
}
int search(int x,int num)
{
int a=node[num].l;
int b=node[num].r;
int mid=(a+b)/2;
if(node[num].h!=0)return node[num].h;
if(a==b)
{
return 0;
}
if(x<=mid)return search(x,num*2+1);
else return search(x,num*2+2);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&build[i].x,&build[i].y,&build[i].h);
xx[i*2 ]=build[i].x;
xx[i*2+1]=build[i].y;
}
sort(xx,xx+n*2);
xnum=1;
for(int i=1;i<n*2;i++)
if(xx[i]!=xx[i-1])xx[xnum++]=xx[i];
for(int i=0;i<n;i++)
{
build[i].x=xun(build[i].x);
build[i].y=xun(build[i].y);
}
creat(0,xnum-1,0,0);
sort(build,build+n);
for(int i=0;i<n;i++)
{
insert(build[i].x,build[i].y-1,build[i].h,0);
}
LL sum=0;
for(int i=0;i<xnum-1;i++)
{
sum+=(long long)(xx[i+1]-xx[i])*search(i,0);
}
cout<<sum<<endl;
}
return 0;
}
1157

被折叠的 条评论
为什么被折叠?



