zoukankan      html  css  js  c++  java
  • 洛谷 P3268 [JLOI2016]圆的异或并 扫描线

    之前做过一到类似的,当时没写题解,今天来补上。

    首先我们发现圆没有交,所以两个圆只有包含和相离两种关系。

    我们考虑用扫描线来处理,随着扫描线的推移,和上面的圆的交点 一直都在 和下面的圆的交点的上面,可以用 (set) 来维护相对位置

    怎么确定一个圆应该是加还是减?我们将圆拆分成上半圆和下半圆,将上半圆插入 (set) 后,找在这扫描线上其下面的那个半圆。

    (1) .若找不到,哪这个圆不会被包含,应该加上

    (2) .若是下半圆,则和那个圆的加减状态相反。

    (3) .若是上半圆,则和那个圆的加减状态相同。

    上面的过程建议画一下图方便理解

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<set>
    #define DB double
    using namespace std;
    int n, tot, now;
    long long ans;
    DB nowx;
    const int N = 200010;
    const DB eps = 1e-9;
    int val[N];
    DB x[N], y[N], r[N];
    struct cir
    {
    	int opt, id;
    	DB nowy()//求圆和当前扫描线交点的y坐标
    	{
    		return y[id] + (DB)opt * sqrt(r[id] * r[id] - (x[id] - nowx) * (x[id] - nowx) + eps);
    	}
    	friend bool operator <(cir x, cir y) {return x.nowy() < y.nowy();}
    };
    set<cir>s;
    set<cir>::iterator it;
    struct xian
    {
    	int opt, x, id;
    	friend bool operator <(const xian &x, const xian &y) {return x.x < y.x;}
    } li[N << 1];
    int main()
    {
    	cin >> n;
    	for (int i = 1; i <= n; ++i)
    	{
    		scanf("%lf%lf%lf", &x[i], &y[i], &r[i]);
    		li[++tot] = (xian) {1, (int)(x[i] - r[i]), i};
    		li[++tot] = (xian) {0, (int)(x[i] + r[i]), i};
    	}
    	sort(li + 1, li + 1 + tot);
    	for (int i = 1; i <= tot; ++i)
    	{
    		nowx = li[i].x;
    		if (li[i].opt)
    		{
    			now = li[i].id; it = s.insert((cir) {1, now}).first;
    			if (it == s.begin())val[now] = 1;
    			else
    			{
    				--it;
    				if ((*it).opt == -1)val[now] = val[(*it).id] ^ 1;
    				else val[now] = val[(*it).id];
    			}
    			s.insert((cir) { -1, now});
    			if (val[now])ans += r[now] * r[now];
    			else ans -= r[now] * r[now];
    		}
    		else s.erase((cir) {1, li[i].id}), s.erase((cir) { -1, li[i].id});
    	}
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    [PKUWC2018][LOJ2537]Minimax(线段树合并)
    [NOI2019][洛谷P5471]弹跳(dijkstra+KD-Tree)
    [BZOJ4770]图样(概率期望、二进制数位dp)
    [SPOJ11482][BZOJ2787]Count on a trie(广义SA+长链剖分+BIT)
    [HEOI/TJOI2016][洛谷P4094]字符串(SA+主席树)
    [BZOJ3270]博物馆(矩阵求逆)
    [NOI2016][洛谷P1117]优秀的拆分(SA)
    [NOI2018][洛谷P4770]你的名字(SAM+SA+主席树)
    设置echarts两个y轴的0点一致
    echarts中饼图或环形图的高亮效果(点击高亮/默认某一条高亮)
  • 原文地址:https://www.cnblogs.com/wljss/p/12658663.html
Copyright © 2011-2022 走看看