zoukankan      html  css  js  c++  java
  • Codeforces 1041E. Divide Square 【扫描线】

    题目链接
    题目描述
    在一个(10^6)x(10^6)的正方形中,给你n条垂直于y中的线和m条垂直于x轴的线,每一条线至少有一个端点和正方形相连。问最后这些组成的线构成了多少个新的小矩阵。
    思路
    考虑扫描线的思想,从左到右对平行于y轴的线的每个x进行扫描。
    每个交点,必定形成一个新的矩形,对于范围为0~1000000的线来说,会额外增加一个区域,那么可以看成在矩形的初始状态就进行了额外的划分。答案就变成了初始所划分好的区域+所有交点数量。
    先将所有水平的线段读入,根据扫描线的思想差分处理l和r+1,然后读入每条垂直的线。排序以后枚举每个x点,就相当于对于x点,求其上下界中点的数量,相当于一个差分以后的前缀和处理,同时每次更新一下整个上下区间的值即可。
    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int N = 1e6 + 10;
    struct edge1 {
    	int x, y, d;
    	friend bool operator < (const edge1 a, const edge1 b) {
    		return a.x < b.x;
    	}
    }a[N << 1];
    struct edge2 {
    	int x, l, r;
    	friend bool operator < (const edge2 a, const edge2 b) {
    		return a.x < b.x;
    	}
    }b[N << 1];
    LL tr[N << 1];
    
    int lowbit(int x) {
    	return x & -x;
    }
    
    void update(int x, int num) {
    	for(int i = x; i <= 1e6 + 2; i += lowbit(i)) tr[i] += num;
    }
    
    LL sum(int x) {
    	LL sum = 0;
    	for(int i = x; i > 0; i -= lowbit(i)) sum += tr[i];
    	return sum;
    }
    
    void solve() {
    	LL res = 1, idx = 0;
    	int n, m; cin >> n >> m;
    	for(int i = 1; i <= n; i++) {
    		int y, l, r; scanf("%d%d%d", &y, &l, &r);
    		if(l == 0 && r == 1e6) res++;
    		a[++idx] = {l, y, 1};
    		a[++idx] = {r + 1, y, -1};
    	}
    	for(int i = 1; i <= m; i++) {
    		int x, l, r; scanf("%d%d%d", &x, &l, &r);
    		if(l == 0 && r == 1e6) res++;
    		b[i] = {x, l, r};
    	}
    	sort(a + 1, a + 1 + idx);
    	sort(b + 1, b + 1 + m);
    	int pt1 = 1, pt2 = 1;
    	for(; pt1 <= idx && a[pt1].x == 0; pt1++) update(a[pt1].y, a[pt1].d);
    
    	for(int i = 1; i <= 1e6 + 10; i++) {
                for(; pt1 <= idx && a[pt1].x == i; pt1++) {
    			update(a[pt1].y, a[pt1].d);
    		}
    	    for(; pt2 <= m && b[pt2].x == i; pt2++)  {
    			res += sum(b[pt2].r) - sum(b[pt2].l - 1);
    		}
    	}
    	printf("%lld
    ", res);
    }
    
    int main() {
    //	freopen("in.txt", "r", stdin);
    	solve();
    	return 0;
    }
    
    
  • 相关阅读:
    分布式哈希和一致性哈希算法
    消息队列rabbitmq的五种工作模式(go语言版本)
    Mysql查询缓存
    数据库的三大设计范式
    二叉树的常见算法
    消息队列选型分析
    Mysql防止索引失效原则
    Mysql索引优化单表、两表、三表实践
    数据结构 【栈与队列】
    谷歌实用插件
  • 原文地址:https://www.cnblogs.com/ZX-GO/p/13557370.html
Copyright © 2011-2022 走看看