• HDU 1542:Atlantis(扫描线+线段树 矩形面积并)***


    题目链接

    题意

    给出n个矩形,求面积并。

    思路

    使用扫描线,我这里离散化y轴,按照x坐标从左往右扫过去。离散化后的y轴可以用线段树维护整个y上面的线段总长度,当碰到扫描线的时候,就可以统计面积。这里要注意线段树上结点维护的是线段的信息,而不是点的信息。
    参考资料

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int INF = 0x3f3f3f3f;
    const int N = 1e5 + 10;
    #define lson l, m, rt<<1
    #define rson m + 1, r, rt<<1|1
    struct Node {
    	int st;
    	double l, r, id;
    	bool operator < (const Node &rhs) const {
    		return id < rhs.id;
    	}
    } p[N];
    double y[N], tree[N<<2];
    int cnt[N<<2];
    
    void PushUp(int l, int r, int rt) {
    	if(cnt[rt] > 0) tree[rt] = y[r+1] - y[l]; // r + 1是因为线段树上结点是线段,映射成点就要+1
    	else if(l == r) tree[rt] = 0; // 当这个线段没有cnt的时候就代表消失了
    	else tree[rt] = tree[rt<<1] + tree[rt<<1|1];
    }
    
    void Update(int L, int R, int w, int l, int r, int rt) {
    	if(L <= l && r <= R) {
    		cnt[rt] += w;
    		PushUp(l, r, rt);
    		return ;
    	}
    	int m = (l + r) >> 1;
    	if(L <= m) Update(L, R, w, lson);
    	if(m < R) Update(L, R, w, rson);
    	PushUp(l, r, rt);
    }
    
    int main() {
    	int cas = 1, n;
    	while(scanf("%d", &n), n) {
    		int cnt = 0, m = 0;
    		for(int i = 1; i <= n; i++) {
    			double x1, x2, y1, y2;
    			scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
    			y[++cnt] = y1, y[++cnt] = y2;
    			p[++m] = (Node) { 1, y1, y2, x1 };
    			p[++m] = (Node) { -1, y1, y2, x2 };
    		}
    		sort(y + 1, y + 1 + cnt);
    		sort(p + 1, p + 1 + m);
    		cnt = unique(y + 1, y + 1 + cnt) - y - 1;
    		double ans = 0;
    		for(int i = 1; i <= m; i++) {
    			ans += tree[1] * (p[i].id - p[i-1].id);
    			int L = lower_bound(y + 1, y + 1 + cnt, p[i].l) - y;
    			int R = lower_bound(y + 1, y + 1 + cnt, p[i].r) - y - 1;
    					// R - 1是因为线段树上的结点是线段
    			Update(L, R, p[i].st, 1, cnt, 1);
    			printf("%d : %d - %d , %.2f
    ", i, L, R, tree[1]);
    		}
    		printf("Test case #%d
    ", cas++);
    		printf("Total explored area: %.2f
    
    ", ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    c# – 通过反射获取命名空间中的所有类型
    宝塔任务计划通道设置
    DRF项目框架基础设计
    Redis-数据特征和应用场景
    Redis-持久化详解
    Dockerfile文件详解
    ntp同步阿里服务器时间(centos)
    NUC8/11更新EC Firmware
    ambarella H2 kernel调试记录
    MobaXterm 执行make menuconfig不能删除字符
  • 原文地址:https://www.cnblogs.com/fightfordream/p/7591674.html
Copyright © 2020-2023  润新知