您的位置:首页 > 其它

hdu 1255 覆盖的面积 离散化+线段树

2012-07-16 11:23 381 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1255

用cnt记录覆盖几次,once与twice表示覆盖一次与两次时的长度

离散后二分查找,开始直接用的map…… 此外代码各种挫……然后就超时了,虽然感觉超时的问题应该不在离散这,但二分还是比map快……

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define LL(x) (x << 1)
#define RR(x) (x << 1 | 1)
using namespace std;
const int maxn= 2010;
const double eps= 1e-8;
struct LINE{
double hei, lef, rig;
int side;
}line[maxn];
struct node{
int lef, rig, mid, cnt;
double once, twice;
}seg[4*maxn];
int n, cnt;
double pos[maxn];
bool cmp( LINE x, LINE y){
return x.hei< y.hei;
}
void init(){
scanf("%d", &n);
int i, j, k;
double x1, y1, x2, y2;
for( i=0, cnt= 0; i<n; i++){
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
pos[cnt]= x1;
line[cnt].hei= y1;
line[cnt].lef= x1;
line[cnt].side= 1;
line[cnt++].rig= x2;

line[cnt].hei= y2;
line[cnt].lef= x1;
line[cnt].rig= x2;
line[cnt].side= -1;
pos[cnt++]= x2;
}
sort( pos, pos+ cnt);
sort( line, line+ cnt, cmp);
for( i=0, cnt= 0; i<2*n; i++){
if( i== 0 || pos[i] != pos[i-1])
pos[cnt++]= pos[i];
}
}
void maketree(int num, int lef, int rig){
seg[num].lef= lef;
seg[num].rig= rig;
seg[num].mid= (lef + rig) >> 1;
seg[num].cnt= 0;
seg[num].once= seg[num].twice= 0.0;
if( lef != rig){
maketree( LL(num), lef, seg[num].mid);
maketree( RR(num), seg[num].mid+1, rig);
}
}
int binary( double x){
int l= 0, r= cnt-1, mid;
while( l <= r){
mid= (l+ r)>> 1;
if( fabs(x- pos[mid]) <eps) break;
else if( x- pos[mid] < 0) r= mid - 1;
else l= mid + 1;
}
return mid;
}
void update( int num){
if( seg[num].cnt > 0)
seg[num].once= pos[seg[num].rig + 1]- pos[seg[num].lef];
else if( seg[num].lef== seg[num].rig)
seg[num].once= 0;
else
seg[num].once= seg[LL(num)].once + seg[RR(num)].once;

if( seg[num].cnt > 1)
seg[num].twice= pos[seg[num].rig + 1]- pos[seg[num].lef];
else if( seg[num].lef == seg[num].rig)
seg[num].twice= 0;
else if( seg[num].cnt == 1)
seg[num].twice= seg[RR(num)].once + seg[LL(num)].once;
else
seg[num].twice= seg[LL(num)].twice + seg[RR(num)].twice;

}
void insert( int num, int lef, int rig, int val){
if( seg[num].lef== lef && seg[num].rig == rig){
seg[num].cnt+= val;
update( num);
return ;
}
if( lef > seg[num].mid) insert( RR(num), lef, rig, val);
else if( rig<= seg[num].mid) insert( LL(num),lef, rig, val);
else {
insert( LL(num), lef, seg[num].mid, val);
insert( RR(num), seg[num].mid+1, rig, val);
}
update(num);
}
void handle(){
int x1, x2, y1, y2;
int i, j, k;
double ans= 0;
for( i=0; i<2*n-1; i++){
x1= binary( line[i].lef);
x2= binary( line[i].rig) - 1;
insert( 1, x1, x2, line[i].side);
ans+= seg[1].twice *( line[i+1].hei - line[i].hei);
}
printf("%.2f\n", ans);
}
int main(){
// freopen("1.txt", "r", stdin);
int i, j, k, T;
scanf("%d", &T);
while( T--){
init();
maketree(1, 0, cnt-1);
handle();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: