跟1264差不多,但是需要注意就是只计算覆盖度大于等于2的长度,要记住修改时要修改所有子节点
3109msC++代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> using namespace std; const int NUM = 2000; typedef struct line { double x,y1,y2; int flag; }; typedef struct node { int left,mid,right,key; double len; }node; line lines[NUM]; node T[ NUM<<2 ]; double Y[NUM];//存储离散化的纵坐标 void create(int u,int l,int r) { T[u].left = l; T[u].right = r; T[u].key = 0; T[u].len = 0.0; T[u].mid = (l+r)>>1; if(r == l + 1) return; create(u+u,l,T[u].mid); create(u+u+1,T[u].mid,r); } void inquiry(int i) { if(T[i].key > 1) //有覆盖 { T[i].len = Y[T[i].right] - Y[T[i].left]; } else if (T[i].right - T[i].left == 1) { T[i].len = 0.0; } // 其他情况 else { T[i].len = T[i+i].len + T[i+i+1].len; } } void change(line li,int i) { if (Y[T[i].left] == li.y1 && Y[T[i].right] == li.y2) { // “左”边flag是1 “右”边flag是-1 // 其实是计算完一个矩形的面积之和,cover减去1 // 就相当于把这个矩形擦除掉了 T[i].key += li.flag; } if((T[i].left + 1) < T[i].right) { int m = (T[i].left + T[i].right) >> 1; if (li.y1 >= Y[m]) { change(li, i+i+1); } else if (li.y2 <= Y[m]) { change(li, i+i); } else { line ll, lr; ll.y1 = li.y1; ll.y2 = Y[m]; ll.flag = li.flag; lr.y1 = Y[m]; lr.y2 = li.y2; lr.flag = li.flag; change(ll, i+i); change(lr, i+i+1); } } // 每次插入节点后,计算覆盖的长度 inquiry(i); } bool cmp(const line& lhs, const line& rhs) { return lhs.x < rhs.x; } /*读入左竖边时,按左竖边的长度作为高来计算; 读入右竖边时,把右竖边覆盖的Y轴范围释放1, 删除一个与之对应的左竖边对覆盖Y轴的影响, 交给其前面的某个左竖边来确定覆盖范围;*/ int main() { double x1,y1,x2,y2; int n,t,m,j; scanf("%d",&t); while(t--) { scanf("%d",&m); int i = 1; for(j = 1; j <= m; j++) { scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); if (y1 > y2) { swap(y1, y2); } // 左边的边横坐标是x1,所以x1必须是小的一个 if (x1 > x2) { swap(x1, x2); } lines[i].x = x1; lines[i].y1 = y1; lines[i].y2 = y2; lines[i].flag = 1; Y[i++] = y1; lines[i].x = x2; lines[i].y1 = y1; lines[i].y2 = y2; lines[i].flag = -1; // 抵消上次的覆盖 Y[i++] = y2; } n = i - 1; sort(Y+1,Y+n+1); sort(lines+1,lines+n+1,cmp); create(1,1,n); change(lines[1],1); double ans = 0.0; for(i = 2; i <= n ; i++) { ans += T[1].len * (lines[i].x - lines[i-1].x); change(lines[i],1); } printf("%.2lf\n", ans); } return 0; }