poj 3277 线段树求区间并1

来源:互联网 发布:古筝在线弹奏软件 编辑:程序博客网 时间:2024/05/21 12:43

所有矩形有相同的下边界,求 并 的面积


#include <stdio.h>#include <algorithm>using namespace std;#define N 80001#define L(i) i<<1#define R(i) i<<1|1struct City{    __int64 l,r,h;    void input()    {        scanf("%I64d%I64d%I64d",&l,&r,&h);    }}building[N];struct node{    int l,r;    __int64 h;    int mid()    {        return (l + r)>>1;    }}st[N<<2];bool cmp(City a,City b){    return a.h < b.h;}int n,top;__int64 hash[N];__int64 sum;int bs(__int64 s){    int mid,l = 0, r = top -1;    while(l <= r)    {        mid = (l + r)>>1;        if(hash[mid] == s)            return mid;        if(hash[mid] < s)            l = mid + 1;        else            r = mid - 1;    }    return -1;}void build(int l,int r,int id){    st[id].l = l;    st[id].r = r;    st[id].h = 0;    if(l + 1 != r)///叶子结点    {        int mid = st[id].mid();        build(l,mid,L(id));        build(mid,r,R(id));    }}void insert(int l,int r,__int64 h,int id){    if(st[id].l == l && st[id].r == r)    {        st[id].h = h;        return ;    }    if(st[id].h)    {        st[L(id)].h = st[R(id)].h = st[id].h;        st[id].h = 0;    }    int mid = st[id].mid();    if(mid >= r)        insert(l,r,h,L(id));    else if(mid <= l)        insert(l,r,h,R(id));    else    {        insert(l,mid,h,L(id));        insert(mid,r,h,R(id));    }}void query(int id){    if(st[id].h)    {        sum += st[id].h * (hash[st[id].r] - hash[st[id].l]);        return ;    }    if(st[id].l + 1 == st[id].r)        return ;    query(L(id));    query(R(id));}int main(){    scanf("%d",&n);    top = 0;    int i;    for(i = 0; i < n ; ++i)    {        building[i].input();        hash[top++] = building[i].l;        hash[top++] = building[i].r;    }    sort(hash,hash+top);    sort(building,building + n, cmp);    int m = top;    top = 1;    for(i = 1;i < m; ++i)///离散化        if(hash[i] != hash[i-1])            hash[top++] = hash[i];    build(0,top - 1,1);    for(i = 0;i < n; ++i)    {        int a = bs(building[i].l),b = bs(building[i].r);        insert( a, b,building[i].h,1);    }    sum = 0;    query(1);    printf("%I64d\n",sum);    return 0;}/*42 5 19 10 46 8 24 6 316*/