来源:http://poj.org/problem?id=3277
题意:给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积。
思路:因为矩形的区间范围太大,因此可以离散化,离散化后就是一个线段树的问题了。结点信息包括左端点,右端点,和高度。一般来说,线段树建树有两种方法,一种是区间离散,一种是点离散,以前只写过点离散的,而这道题明显 是区间离散更简单。又学了一点新知识。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 40010;
LL ans = 0;
int cnt = 0;
struct tree{
int lp,rp,hei;
int getmid(){
return (lp + rp) / 2;
}
}tt[N * 8];
int vv[N * 2];
struct interval{
int lpos,rpos,hei;
}aa[N];
void built_tree(int lp,int rp,int pos){
tt[pos].lp = lp;
tt[pos].rp = rp;
tt[pos].hei = 0;
if(lp + 1 == rp)
return;
int mid = tt[pos].getmid();
built_tree(lp,mid,pos*2);
built_tree(mid,rp,pos*2+1);
}
bool cmp(interval a,interval b){
return a.hei < b.hei;
}
int binary_search(int lp,int rp,int value){
while(lp <= rp){
int mid = (lp + rp) / 2;
if(vv[mid] == value)
return mid;
else if(vv[mid] > value)
rp = mid - 1;
else
lp = mid + 1;
}
}
void update(int lp,int rp,int value,int pos){
if(lp == tt[pos].lp && tt[pos].rp == rp){
tt[pos].hei = value;
return;
}
if(tt[pos].hei >= 0 && tt[pos].rp > tt[pos].lp + 1){
tt[2*pos].hei = tt[2*pos+1].hei = tt[pos].hei;
tt[pos].hei = -1;
}
int mid = tt[pos].getmid();
if(rp <= mid)
update(lp,rp,value,pos * 2);
else if(lp >= mid)
update(lp,rp,value,pos * 2 + 1);
else{
update(lp,mid,value,pos * 2);
update(mid,rp,value,pos * 2 + 1);
}
}
long long query(int pos){
if(tt[pos].hei >= 0){
return tt[pos].hei * (long long)(vv[tt[pos].rp] - vv[tt[pos].lp]);
}
else
return query(2 * pos) + query(2 * pos + 1);
}
int main(){
//freopen("1.txt","r",stdin);
int n;
while(scanf("%d",&n) != EOF){
cnt = 1;
memset(vv,0,sizeof(vv));
for(int i = 0; i < n; ++i){
scanf("%d%d%d",&aa[i].lpos,&aa[i].rpos,&aa[i].hei);
vv[cnt++] = aa[i].lpos;
vv[cnt++] = aa[i].rpos;
}
sort(vv + 1,vv + cnt );
int k = 0;
for(int i = 1; i <= cnt; ++i){
if(vv[i] != vv[i-1] || i == 1)
vv[++k] = vv[i];
}
cnt = k - 1;
built_tree(1,cnt,1);
sort(aa,aa + n, cmp);
for(int i = 0; i < n; ++i){
int xid = binary_search(1,cnt,aa[i].lpos);
int yid = binary_search(1,cnt,aa[i].rpos);
update(xid,yid,aa[i].hei,1);
}
printf("%lld\n",query(1));
}
return 0;
}