hdu 1255 覆盖的面积 离散化+线段树
2012-07-16 11:23
381 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1255
用cnt记录覆盖几次,once与twice表示覆盖一次与两次时的长度
离散后二分查找,开始直接用的map…… 此外代码各种挫……然后就超时了,虽然感觉超时的问题应该不在离散这,但二分还是比map快……
用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(); } }
相关文章推荐
- HDU 1255 覆盖的面积(离散化+线段树)
- HDU 1255 覆盖的面积(线段树+扫描线+离散化)
- HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
- hdu1255 覆盖的面积 线段树+里离散化求矩形面积的交
- HDU-1255 覆盖的面积(线段树扫描线+离散化+改进后超快的算法)
- hdu 1255 覆盖的面积(线段树离散化)
- HDU 1255 覆盖的面积(线段树+离散化+扫描线)
- HDU 1255 覆盖的面积 (线段树+扫描线+离散化)
- hdu 1255 覆盖的面积 (线段树,离散化+扫描线)
- HDU-1255 覆盖的面积(线段树扫描线模板+离散化+加点修改题)
- hdu 1255 覆盖的面积(线段树+离散化+扫描线)
- HDU 1255 覆盖的面积[离散化 + 扫描线 + 线段树]
- HDU 1255 覆盖的面积[离散化 + 扫描线 + 线段树]
- hdu 1255 覆盖的面积(线段树 面积交+离散化)
- HDU 1255 覆盖的面积 (线段树 + 离散化 + 扫描线)
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
- hdu(1255)——覆盖的面积(线段树求面积交)
- 【 HDU 1255】 覆盖的面积(矩阵面积交,线段树,扫描法)
- hdu 1255 覆盖的面积(线段树+扫描线——面积交)
- HDU 1255 覆盖的面积 (线段树扫描线+面积交)