本文主要是介绍poj 3277 City Horizon,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
//数据很大,需要先离散化,然后线段树。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=80005;
struct node{
int left, right, mid, cover;
};
struct seg{int x[2], h;}p[40005];
struct HAS{int x, id;}a[80005];
node seg_tree[4*MAXN];
int n, hash[80005];
void make(int l, int r, int num){
seg_tree[num].left=l;
seg_tree[num].right=r;
seg_tree[num].mid=(l+r)/2;
seg_tree[num].cover=0;
if(l+1!=r){
make(l, seg_tree[num].mid, num*2);
make(seg_tree[num].mid, r, num*2+1);
}
}
void insert(int l, int r, int h, int num){
if(seg_tree[num].left==l&&seg_tree[num].right==r){
if(seg_tree[num].cover<h)
seg_tree[num].cover=h;
return;
}
if(r<=seg_tree[num].mid)
insert(l, r, h, 2*num);
else if(l>=seg_tree[num].mid)
insert(l, r, h, 2*num+1);
else {
insert(l, seg_tree[num].mid, h, 2*num);
insert(seg_tree[num].mid, r, h, 2*num+1);
}
}
long long cal(int h, int num){ //由于已经离散化,必须到根节点才能计算
if(h>seg_tree[num].cover)
seg_tree[num].cover=h;
if(seg_tree[num].left+1==seg_tree[num].right)
return (long long)(hash[seg_tree[num].right]-hash[seg_tree[num].left])*seg_tree[num].cover;
return cal(seg_tree[num].cover, num*2)+cal(seg_tree[num].cover, num*2+1);
}
bool cmp(HAS t1, HAS t2){
return t1.x<t2.x;
}
void init(){ //离散化
int i, l, r, h, t;
for(i=0; i<n; i++){
scanf("%d%d%d", &p[i].x[0], &p[i].x[1], &p[i].h);
a[i*2].x=p[i].x[0];
a[i*2+1].x=p[i].x[1];
a[i*2].id=i*2;
a[i*2+1].id=i*2+1;
}
sort(a, a+2*n, cmp);
t=1;
hash[t]=p[a[0].id/2].x[a[0].id%2];
p[a[0].id/2].x[a[0].id%2]=1;
for(i=1; i<2*n; i++){
if(a[i].x>a[i-1].x){
hash[++t]=p[a[i].id/2].x[a[i].id%2];
p[a[i].id/2].x[a[i].id%2]=t;
}
else {
hash[t]=p[a[i].id/2].x[a[i].id%2];
p[a[i].id/2].x[a[i].id%2]=t;
}
}
}
int main(){
//freopen("1.txt", "r", stdin);
scanf("%d", &n);
make(1, 80000, 1);
init();
for(int i=0; i<n; i++)
insert(p[i].x[0], p[i].x[1], p[i].h, 1);
printf("%lld\n", cal(0, 1));
return 0;
}
这篇关于poj 3277 City Horizon的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!