poj 3277 City Horizon(线段树+离…

来源:互联网 发布:java使用qq邮箱发邮件 编辑:程序博客网 时间:2024/04/29 13:24
题意:有多栋建筑 它们有不同的高度 从一个面看进入 能看到的总面积


思路:线段树+离散化 因为它们的宽度太大,无法存储 所以得离散
PS:这道题又学到了一些新知道 1、另一种离散化的方法 2、unique 函数的使用

 unique(first,last)
参数 first, last:指出要剔除连续重复元素的迭代器区间[first,last) 右边是开区间
返回值  返回剔除元素后的新区间的最后一个元素的迭代器位置



//   4028K   204MS
#include <stdio.h>
#include <algorithm>
#define M 40050
#define L(x) (x<<1)
#define R(x) ((x<<1)+1)
using namespace std;

struct data
{
    intl,r,h;
}node[8*M];

int seg[2*M],hei[M],lp[M],rp[M];

void BuildTree(int left,int right,int u)
{
    node[u].l =left;
    node[u].r =right;
    node[u].h =0;
    if (left + 1== right)
       return ;
    int mid =(left + right)>>1;
    BuildTree(left,mid,L(u));
    BuildTree(mid,right,R(u));
}

void updata (int left,int right,int i,int u)
{
    if(seg[node[u].l] ==left&&seg[node[u].r] ==right)//找到与原来长度相等的
    {
       if (node[u].h <hei[i])      //比已存在的高 就把它覆盖
           node[u].h = hei[i];
       return ;
    }
    int mid =seg[(node[u].l+node[u].r)>>1];
    if (right<= mid)
       updata (left,right,i,L(u));
    else if(left >= mid)
       updata (left,right,i,R(u));
    else
    {
       updata (left,mid,i,L(u));
       updata (mid,right,i,R(u));
    }
}

__int64 count (int h,intu)   //算每个子结点的面积并
{
    if(node[u].h <h)         //延迟覆盖 父结比子结点高的话
       node[u].h = h;
    if(node[u].l + 1 == node[u].r)
       return (__int64) (seg[node[u].r] - seg[node[u].l])*node[u].h;
    __int64 a =count (node[u].h,L(u));
    __int64 b =count (node[u].h,R(u));
    returna+b;
}
int main ()
{
    intn,m,a,b,i;

    while(~scanf ("%d",&n))
    {
       int k = 0;
       for (i = 1;i <= n;i++)         //离散化操作
       {
           scanf("%d%d%d",&lp[i],&rp[i],&hei[i]);
           seg[++k] = lp[i];
           seg[++k] = rp[i];
       }
       sort (seg+1,seg + k + 1);
       m = unique(seg + 1, seg + k + 1) - seg - 1;

       BuildTree(1,m,1);
       for (i = 1;i <= n;i ++)
           updata (lp[i],rp[i],i,1);
       __int64 ans = count (0,1);
       printf ("%I64d\n",ans);
    }
  return 0;
}