扫描线的模板题,先把信息接收,然后排序,记录下上边和下边,然后用一条虚拟的线从下往上扫。如果我扫到的是下边,那么久用线段树在这个区间内加上1,表示这个区间现在是有的,等我扫描到上边的时候在加上-1,把之前的消掉,然后线段树维护区间内的长度,这里不是直接用下标维护,而是需要另一个数组来维护,每次记录我当前的下标在原本的图中的长度。
在update部分用一个点表示我这个点以后的一个长度为1的区间,然后这样算出来的sum[1]就是我现在线段树里包括的区间大小,然后用现在的区间大小去乘上这一部分的高度,然后每次相加,就可以了
#include<map> #include<set> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define lowbit(x) (x & (-x)) typedef unsigned long long int ull; typedef long long int ll; const double pi = 4.0*atan(1.0); const int inf = 0x3f3f3f3f; const int maxn = 305; const int maxm = 305; using namespace std; int n, m, tol, T; struct Node { double l, r, h; int f; bool operator <(Node a) const { return h < a.h; } }; Node node[maxn]; double a[maxn]; double sum[maxn << 2]; int cnt[maxn << 2]; void init() { memset(sum, 0, sizeof sum); memset(cnt, 0, sizeof cnt); } void pushup(int left, int right, int root) { if(cnt[root] != 0) sum[root] = a[right + 1] - a[left]; else if(left == right) sum[root] = 0; else sum[root] = sum[root << 1] + sum[root << 1 | 1]; } void update(int left, int right, int prel, int prer, int val, int root) { if(prel <= left && right <= prer) { cnt[root] += val; pushup(left, right, root); return ; } int mid = (left + right) >> 1; if(prel <= mid) update(left, mid, prel, prer, val, root << 1); if(prer > mid) update(mid+1, right, prel, prer, val, root << 1 | 1); pushup(left, right, root); } int main() { int cas = 1; while(scanf("%d", &n)== 1 && n) { init(); double x1, y1, x2, y2; for(int i=1; i<=n; i++) { scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); node[2*i-1].l = x1; node[2*i].l = x1; node[2*i-1].r = x2; node[2*i].r = x2; node[2*i-1].h = y1; node[2*i].h = y2; node[2*i-1].f = 1; node[2*i].f = -1; a[2*i-1] = x1; a[2*i] = x2; } n = 2*n; sort(node+1, node+1+n); sort(a+1, a+1+n); int nn = unique(a+1, a+1+n) - (a+1); double ans = 0; for(int i=1; i<n; i++) { int l = lower_bound(a+1, a+1+nn, node[i].l) - a; int r = lower_bound(a+1, a+1+nn, node[i].r) - a; update(1, nn, l, r-1, node[i].f, 1); ans += (node[i+1].h - node[i].h) * sum[1]; } printf("Test case #%d\n", cas++); printf("Total explored area: %0.2f\n", ans); printf("\n"); } return 0; }
原文地址:https://www.cnblogs.com/H-Riven/p/9356322.html
时间: 2024-10-12 13:44:14