线段树
来源:互联网 发布:黔马网络 编辑:程序博客网 时间:2024/05/18 00:24
线段树
/**** **** **** **** **** ****
* Function Name : 线段树
* Description : HDOJ 1542 Atlantis
* 用于表示区间线段
**** **** **** **** **** ****/
#include<cstdio>
#include<algorithm>
using namespace std;
typedef struct ITREE_NODE {
ITREE_NODE * pLChild, * pRChild;
double left, right; // 左端点,右端点
double measure; // 测度
int count; // 覆盖计数器
int lines; // 独立线段数
int lbound, rbound; // 覆盖左、右顶点的线段数目
}*PITREE_NODE;
inline void safe_add(int & v, int value) {
v += value;
if (v < 0) v = 0;
}
void itree_splite(const double * pList, PITREE_NODE pParent, const int iLeft, const int iRight) {
if (iRight - iLeft <= 1) return;
int iMid = (iLeft + iRight) >> 1;
pParent -> pLChild = new ITREE_NODE;
pParent -> pRChild = new ITREE_NODE;
memset(pParent -> pLChild, 0, sizeof(ITREE_NODE));
memset(pParent -> pRChild, 0, sizeof(ITREE_NODE));
pParent -> pLChild -> left = pList[iLeft];
pParent -> pLChild -> right = pList[iMid];
pParent -> pRChild -> left = pList[iMid];
pParent -> pRChild -> right = pList[iRight];
itree_splite(pList, pParent -> pLChild, iLeft, iMid);
itree_splite(pList, pParent -> pRChild, iMid, iRight);
}
PITREE_NODE itree_generate(const double * pList, const int iListCount) {
PITREE_NODE pRoot = new ITREE_NODE;
memset(pRoot, 0, sizeof(ITREE_NODE));
pRoot -> left = pList[0];
pRoot -> right = pList[iListCount - 1];
itree_splite(pList, pRoot, 0, iListCount - 1);
return pRoot;
}
void itree_destroy(PITREE_NODE pParent) {
if (pParent == NULL) return;
if (pParent -> pLChild) itree_destroy(pParent -> pLChild);
if (pParent -> pRChild) itree_destroy(pParent -> pRChild);
delete pParent;
}
inline void itree_measure(PITREE_NODE pNode) {
if (pNode -> count > 0)
pNode -> measure = pNode -> right - pNode -> left;
else if (pNode -> pLChild && pNode -> pRChild)
pNode -> measure = pNode -> pLChild -> measure + pNode -> pRChild -> measure;
else
pNode -> measure = 0;
}
inline void itree_lines(PITREE_NODE pNode) {
if (pNode -> count > 0) {
pNode -> lines = 1;
} else if (pNode -> pLChild && pNode -> pRChild) {
if (pNode -> pLChild -> rbound && pNode -> pRChild -> lbound) {
pNode -> lines = pNode -> pLChild -> lines + pNode -> lines - 1;
} else {
pNode -> lines = pNode -> pLChild -> lines + pNode -> lines;
}
} else {
pNode -> lines = 0;
}
}
// 插入的时候value = 1, 删除的时候value = -1
void itree_update(PITREE_NODE pParent, const double left, const double right,
int value) {
if (pParent -> left == left && pParent -> right == right) {
safe_add(pParent -> count, value);
safe_add(pParent -> lbound, value);
safe_add(pParent -> rbound, value);
itree_measure(pParent);
itree_lines(pParent);
} else {
if (pParent -> pLChild -> right > left) {
if (pParent -> pLChild -> right >= right) {
itree_update(pParent -> pLChild, left, right, value);
} else {
itree_update(pParent -> pLChild, left,
pParent -> pLChild -> right, value);
itree_update(pParent -> pRChild, pParent -> pRChild -> left,
right, value);
}
} else {
itree_update(pParent -> pRChild, left, right, value);
}
itree_measure(pParent);
itree_lines(pParent);
if (left == pParent -> left) safe_add(pParent -> lbound, value);
if (right == pParent -> right) {
safe_add(pParent -> rbound, value);
}
}
}
void itree_insert(PITREE_NODE pParent, const double left, const double right) {itree_update(pParent, left, right, 1);}
void itree_delete(PITREE_NODE pParent, const double left, const double right) {itree_update(pParent, left, right, -1);}
struct EVENT {
double x, y1, y2;
int type;
};
bool cmp(const EVENT & a, const EVENT & b)
{ return a.x < b.x;}
PITREE_NODE pRoot;
EVENT env[200];
double Y[200];
double tsize = 0.0;
int main() {
double x1, x2, y1, y2;
int i, n, n2, cas = 0;
while (scanf("%d", & n) == 1 && n) {
cas++;
n2 = n << 1;
for (i = 0; i < n2; i += 2) {
scanf("%lf%lf%lf%lf", & x1, & y1, & x2, & y2);
env[i].x = x1;
env[i].y1 = y1;
env[i].y2 = y2;
env[i].type = 1;
env[i + 1].x = x2;
env[i + 1].y1 = y1;
env[i + 1].y2 = y2;
env[i + 1].type = -1;
Y[i] = y1;
Y[i + 1] = y2;
}
sort(env, env + n2, cmp);
sort(Y, Y + n2);
pRoot = itree_generate(Y, n2);
for (i = 0; i < n2; ++i) {
if (i > 0) tsize += pRoot -> measure * (env[i].x - env[i - 1].x);
else tsize = 0.0;
itree_update(pRoot, env[i].y1, env[i].y2, env[i].type);
}
itree_destroy(pRoot);
printf("Test case #%d\nTotal explored area: %.2lf\n\n", cas, tsize);
}
return 0;
}
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 指了指桌上的可乐,刘若英说…
- 年份相加减
- $SECONDS
- android-Building Accessibility Services
- java移位运算符(运算符)
- 线段树
- Leetcode no. 72
- Android网络框架Volley
- 圆形指示器radialIndicator控件的使用
- java 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,
- Android 整体大纲
- 获取远程访问用户的Ip地址
- 记录一下
- ubuntu 源仓库说明