对于x坐标先进行一个排序 用一个数组记录它们是第几大 这样就把非常大的数压缩得很小 线段树中叶子节点记录的就是相邻x的区间
对于每个节点记录最高的h hcount代表这个区间有多少个高度 最后用每个区间宽度×h 在树中即可计算area
对于每个节点记录最高的h hcount代表这个区间有多少个高度 最后用每个区间宽度×h 在树中即可计算area
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
struct node
{
node * pl, * pr;
int iL, iR;
int height;
int hCount;
}line[160008];
int x1[40002], x2[40002];
int x[80004];
int xh[80004];
int h[40002];
int n;
int lineCount;
__int64 area;
node * newNode()
{
node *pt = &line[lineCount++];
memset(pt,0,sizeof(node));
return pt;
}
node * makeTree(int i, int j)
{
node * root=newNode();
root->iL=i;
root->iR=j;
if(j-i>1)
{
int mid=(i+j)/2;
root->pl=makeTree(i,mid);
root->pr=makeTree(mid,j);
}
return root;
}
void height(node * root, int h)
{
root->hCount=1;
root->height=h;
}
void update(node * root, int x1, int x2, int h)
{
if(x[root->iL]==x1 && x[root->iR]==x2 && h > root->height)
{
height(root,h);
return;
}
if(root->iR - root->iL <= 1)
return;
if(root->hCount==1)
{
if(root->height >= h)
return;
height(root->pl,root->height);
height(root->pr,root->height);
}
root->hCount=2;
if(root->height < h)root->height=h;
if(x[root->pl->iR]>x1)
{
if(x[root->pl->iR]>=x2)
update(root->pl, x1, x2, h);
else
{
int mid=(root->iL + root->iR)/2;
update(root->pl,x1,x[mid],h);
update(root->pr,x[mid],x2,h);
}
}
else
{
update(root->pr,x1,x2,h);
}
}
void count(node * root, int i, int j)
{
if(root->hCount==1)
{
__int64 a, b;
a=x[root->iR]-x[root->iL];
b=root->height;
area+=a*b;
return;
}
if(root->iR - root->iL <= 1 || root->hCount==0)
return;
if(root->pl->iR>i)
{
if(root->pl->iR>=j)
{
count(root->pl,i,j);
}
else
{
int mid=(root->iL+root->iR)/2;
count(root->pl,i,mid);
count(root->pr,mid,j);
}
}
else
{
count(root->pr,i,j);
}
}
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int main()
{
while(scanf("%d", &n) ==1)
{
memset(x,0,sizeof(x));
memset(x1,0,sizeof(x1));
memset(x2,0,sizeof(x2));
memset(xh,0,sizeof(xh));
memset(h,0,sizeof(h));
area=0;
int i;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&x1[i],&x2[i],&h[i]);
xh[2*i]=x1[i];
xh[2*i+1]=x2[i];
}
qsort(xh,2*n,sizeof(xh[0]),cmp);
int max_i=0;
for(i=0;i<2*n;i++)
if(xh[i]!=xh[i-1] || i==0)
x[max_i++]=xh[i];
/* for(i=0;i<max_i;i++)
printf("%d ", x[i]);
printf("\n");
*/
lineCount=0;
node * root=makeTree(0,max_i-1);
for(i=0;i<n;i++)
{
update(root,x1[i],x2[i],h[i]);
}
count(root,0,max_i-1);
printf("%I64d\n",area);
}
return 0;
}
#include<math.h>
#include<string.h>
#include<stdlib.h>
struct node
{
node * pl, * pr;
int iL, iR;
int height;
int hCount;
}line[160008];
int x1[40002], x2[40002];
int x[80004];
int xh[80004];
int h[40002];
int n;
int lineCount;
__int64 area;
node * newNode()
{
node *pt = &line[lineCount++];
memset(pt,0,sizeof(node));
return pt;
}
node * makeTree(int i, int j)
{
node * root=newNode();
root->iL=i;
root->iR=j;
if(j-i>1)
{
int mid=(i+j)/2;
root->pl=makeTree(i,mid);
root->pr=makeTree(mid,j);
}
return root;
}
void height(node * root, int h)
{
root->hCount=1;
root->height=h;
}
void update(node * root, int x1, int x2, int h)
{
if(x[root->iL]==x1 && x[root->iR]==x2 && h > root->height)
{
height(root,h);
return;
}
if(root->iR - root->iL <= 1)
return;
if(root->hCount==1)
{
if(root->height >= h)
return;
height(root->pl,root->height);
height(root->pr,root->height);
}
root->hCount=2;
if(root->height < h)root->height=h;
if(x[root->pl->iR]>x1)
{
if(x[root->pl->iR]>=x2)
update(root->pl, x1, x2, h);
else
{
int mid=(root->iL + root->iR)/2;
update(root->pl,x1,x[mid],h);
update(root->pr,x[mid],x2,h);
}
}
else
{
update(root->pr,x1,x2,h);
}
}
void count(node * root, int i, int j)
{
if(root->hCount==1)
{
__int64 a, b;
a=x[root->iR]-x[root->iL];
b=root->height;
area+=a*b;
return;
}
if(root->iR - root->iL <= 1 || root->hCount==0)
return;
if(root->pl->iR>i)
{
if(root->pl->iR>=j)
{
count(root->pl,i,j);
}
else
{
int mid=(root->iL+root->iR)/2;
count(root->pl,i,mid);
count(root->pr,mid,j);
}
}
else
{
count(root->pr,i,j);
}
}
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int main()
{
while(scanf("%d", &n) ==1)
{
memset(x,0,sizeof(x));
memset(x1,0,sizeof(x1));
memset(x2,0,sizeof(x2));
memset(xh,0,sizeof(xh));
memset(h,0,sizeof(h));
area=0;
int i;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&x1[i],&x2[i],&h[i]);
xh[2*i]=x1[i];
xh[2*i+1]=x2[i];
}
qsort(xh,2*n,sizeof(xh[0]),cmp);
int max_i=0;
for(i=0;i<2*n;i++)
if(xh[i]!=xh[i-1] || i==0)
x[max_i++]=xh[i];
/* for(i=0;i<max_i;i++)
printf("%d ", x[i]);
printf("\n");
*/
lineCount=0;
node * root=makeTree(0,max_i-1);
for(i=0;i<n;i++)
{
update(root,x1[i],x2[i],h[i]);
}
count(root,0,max_i-1);
printf("%I64d\n",area);
}
return 0;
}