求周長的做法是對每個段,用線段樹計算出不相交的區間個數,至於求區間個數,有點像掃瞄線的做法,也是先排序,排序之後就是求括號序列有多少個區間,很有技巧。然後就是段的長度*區間個數*2,然後對矩形座標進行關於y=x對稱,再做一次就是完整的周長了。受求周長做法的啟發,可以得到求矩形交面積的做法,需要乙個一維線段樹,記錄x方向線段的資訊,還要乙個二維線段樹記錄各部分是否被覆蓋,一維線段樹在某線段處add=1且掃瞄的線段為+時記錄下y的位置,到add=2且掃瞄線段為-時記錄下y的位置,這兩個y以及x的線段就是交的部分,放入二維線段樹中。這樣迴圈完了之後再計算出二維線段樹包含的面積。
周長的程式我寫了(poj1177),感覺學了不少,這裡的線段樹比一般的線段樹更精妙些,不預先建立,需要時才建立,可以沒有左孩子或右孩子,這並非是為了效率,而是為了便於左右孩子繼承節點的add值。
矩形交面積的做法只是推想而已。
#include #include using namespace std;
long n;
struct tagrect
rects[5000];
short xmin,xmax,ymin,ymax;
short ins_left, ins_right, ins_add;
struct tagedge
inline bool operator < (const tagedge& edge) const
else if (y > edge.y)
else
else
}return y < edge.y;
}}edges[10000];
struct tagsegtreenode
}segtree[1 << 16];
void input(void)
}long insert(long pos)
short mid = ((node.left + node.right) >> 1);
if (ins_right <= mid)
return insert(pos);
} else if (ins_left >= mid)
return insert(pos);
} pos <<= 1;
if (!node.blc)
retval = insert(pos);
++pos;
if (!node.brc)
retval += insert(pos);
return retval;
}inline long insert(long pos, short left, short right, short add)
long calchorzlen(void)
sort(edges, edges + (n << 1));
long retval = 0;
segtree[1].set(xmin, xmax, 0);
for (i = 0; i < (n << 1); ++i)
return retval;
}int main(void)
swap(xmin, ymin);
swap(xmax, ymax);
l += calchorzlen();
l <<= 1;
printf("%d/n", l);
return 0;
}
線段樹矩形面積並,面積交,周長並
include include include include using namespace std const int maxn 2000 10 define lson l,mid,rt 1 define rson mid 1,r,rt 1 1 struct rec rec maxn 2 str...
hdu 1255 覆蓋的面積(線段樹求面積交)
給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區域的面積.雖說覆蓋兩次區域的面積,但是這道題實際上就是求矩形的面積交。膜拜能夠想出這種解法的神牛,竟然能把實際的東西用這麼抽象的語言表示出來,實在是佩服,現在關於掃瞄線的題才做了幾道,沒有對其深刻理解,但是多練總可以理解的,奮鬥吧!acmer!我是...
線段樹 面積交
給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區域的面積.input輸入資料的第一行是乙個正整數t 1 t 100 代表測試資料的數量.每個測試資料的第一行是乙個正整數n 1 n 1000 代表矩形的數量,然後是n行資料,每一行包含四個浮點數,代表平面上的乙個矩形的左上角座標和右下角座標,矩形的...