ACM: 线段树 poj 3277

来源:互联网 发布:java回退流 编辑:程序博客网 时间:2024/06/04 18:30
CityHorizon

Description

Farmer John has taken his cows on a trip to the city! As the sunsets, the cows gaze at the city horizon and observe the beautifulsilhouettes formed by the rectangular buildings.

The entire horizon is represented by a number line with N(1 ≤ N ≤ 40,000) buildings. Building i's silhouettehas a base that spans locations Ai throughBi along the horizon (1 ≤ Ai< Bi ≤ 1,000,000,000) and hasheight Hi (1 ≤ Hi ≤1,000,000,000). Determine the area, in square units, of theaggregate silhouette formed by all N buildings.

Input

Line 1: A singleinteger: N
Lines 2..N+1: Input line i+1 describes buildingi with three space-separated integers: Ai,Bi, and Hi

Output

Line 1: The totalarea, in square units, of the silhouettes formed by all Nbuildings

Sample Input

4
2 5 1
9 10 4
6 8 2
4 6 3

Sample Output

16

Hint

The first buildingoverlaps with the fourth building for an area of 1 square unit, sothe total area is just 3*1 + 1*4 + 2*2 + 2*3 - 1 = 16.
 
题意:给出你矩形的[A,B]长度区间和高度H, 求全部的矩形面具和, 覆盖部分只算一次.
 
解题思路:
    1.经典线段树求矩形面积. 高度离散化即可. (值得多次回味的题目)
 
代码:
#include<cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 400005
struct Line
{
 __int64 x, h;
 int flag;
}line[MAX*2];
struct node
{
 int l, r;
 __int64 h, height;
 int flag;
}pt[MAX*4];
int n;
__int64 y[MAX];
int A, B, H;
inline __int64max(__int64 a, __int64 b)
{
 return a > b ? a : b;
}
bool cmp(Line a,Line b)
{
 if(a.x == b.x) return a.h <b.h;
 else return a.x < b.x;
}
void buildTree(intl, int r, int pos)
{
 pt[pos].l = l, pt[pos].r = r;
 pt[pos].h = pt[pos].flag = 0;
 if(l == r)
 {
  pt[pos].height = y[l];
  return ;
 }
 int mid = (l+r)/2;
 buildTree(l, mid, pos*2);
 buildTree(mid+1, r, pos*2+1);
 pt[pos].height = max(pt[pos*2].height,pt[pos*2+1].height);
}
void insert(int num,int pos)
{
 if(pt[pos].l == pt[pos].r)
 {
  pt[pos].flag +=line[num].flag;
  if(pt[pos].flag> 0) pt[pos].h = pt[pos].height;
  else pt[pos].h = 0;
  return ;
 }
 if(line[num].h <=pt[pos*2].height)
  insert(num, pos*2);
 else
  insert(num, pos*2+1);
 pt[pos].h = max(pt[pos*2].h,pt[pos*2+1].h);
}
int main()
{
 int i;
// freopen("input.txt","r",stdin);
 while(scanf("%d",&n) !=EOF)
 {
  for(i = 0; i <n; ++i)
  {
   scanf("%d %d%d",&A, &B,&H);
   line[i*2].x =A;
   line[i*2].h =H;
   line[i*2].flag= 1;
   line[i*2+1].x= B;
   line[i*2+1].h= H;
   line[i*2+1].flag= -1;
   y[i] =H;
  }
  sort(y, y+n);
  sort(line, line+2*n,cmp);
  buildTree(0, n-1, 1);
  
  insert(0, 1);
  __int64 result = 0;
  for(i = 1; i <n*2; ++i)
  {
   result +=(line[i].x-line[i-1].x)*pt[1].h;
   insert(i,1);
  }
  printf("%I64d\n",result);
 }
 return 0;
}
0 0
原创粉丝点击