zoukankan      html  css  js  c++  java
  • 【BZOJ 4561】【JLOI 2016】圆的异或并

    http://www.lydsy.com/JudgeOnline/problem.php?id=4561
    一开始并不会做,后来看题解看懂了。
    看懂了之后还是错了好几次,数组大小手残开小了。
    圆的包含并不包括内切!
    具体做法是扫描线, 维护扫描线中的圆和一个垂直于x轴的直线的交点,在扫描线中交点的纵坐标是递增的,每个圆和这条直线有两个交点。
    遇到一个圆的左端点,查询它的upper_bound,如果upper_bound是一个圆的上半弧的交点,则它被这个圆包含;如果是一个圆的下半弧的交点,则它和这个圆被包含的状况相同。
    然后把它的上半弧和下半弧加入扫描线,为了之后计算交点。
    遇到一个圆的右端点,删除它的上半弧和下半弧。
    圆只有相离和包含保证了扫描线的正确性。
    扫描线可以用splay,set或fhqtreap维护,小神说总之是能查前驱后继的东东
    今天终于会用set啦~~~

    #include<set>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 200003;
    int in() {
    	int k = 0, fh = 1; char c = getchar();
    	for (; c < '0' || c > '9'; c = getchar())
    		if (c == '-') fh = -1;
    	for (; c >= '0' && c <= '9'; c = getchar())
    		k = k * 10 + c - 48;
    	return k * fh;
    }
    
    struct Circle {
    	int x, y, r;
    	Circle(int _x = 0, int _y = 0, int _r = 0)
    		: x(_x), y(_y), r(_r) {}
    } C[N];
    
    struct Point {
    	int id, x, mark;
    	Point(int _id = 0, int _x = 0, int _mark = 0)
    		: id(_id), x(_x), mark(_mark) {}
    	bool operator < (const Point &A) const {
    		return x < A.x;
    	}
    } P[N << 1];
    
    struct node {
    	int id, mark;
    	node(int _id = 0, int _mark = 0)
    		: id(_id), mark(_mark) {}
    };
    
    ll sqr(int x) {return 1ll * x * x;}
    
    int n, tot = 0, nowx, k[N];
    
    set <node> S;
    set <node> :: iterator tmp;
    
    bool operator < (node A, node B) {
    	double Y1 = (double) C[A.id].y + (double) A.mark * sqrt(sqr(C[A.id].r) - sqr(C[A.id].x - nowx));
    	double Y2 = (double) C[B.id].y + (double) B.mark * sqrt(sqr(C[B.id].r) - sqr(C[B.id].x - nowx));
    	return Y1 != Y2 ? Y1 < Y2 : A.mark < B.mark;
    }
    
    ll ans = 0;
    
    int main() {
    	int x, y, r;
    	n = in();
    	for (int i = 1; i <= n; ++i) {
    		x = in(); y = in(); r = in();
    		C[i] = Circle(x, y, r);
    		P[++tot] = Point(i, x - r, 1);
    		P[++tot] = Point(i, x + r, -1);
    	}
    	sort(P + 1, P + tot + 1);
    	for (int i = 1; i <= tot; ++i) {
    		nowx = P[i].x;
    		if (P[i].mark == 1) {
    			tmp = S.upper_bound(node(P[i].id, 1));
    			if (tmp == S.end())
    				k[P[i].id] = 1;
    			else
    				if (tmp->mark == 1)
    					k[P[i].id] = -k[tmp->id];
    				else
    					k[P[i].id] = k[tmp->id];
    			S.insert(node(P[i].id, 1));
    			S.insert(node(P[i].id, -1));
    		} else {
    			S.erase(node(P[i].id, 1));
    			S.erase(node(P[i].id, -1));
    		}
    	}
    	
    	for(int i = 1; i <= n; ++i)
    		ans += sqr(C[i].r) * k[i];
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    python(六):反射
    python模块之contexlib
    python(五):元类与抽象基类
    python之hashlib模块
    python(四):面型对象--类的特殊方法
    20145226夏艺华 《Java程序设计》第1周学习总结
    20145226夏艺华 《Java程序设计》第10周学习总结
    20145226夏艺华 《Java程序设计》实验报告四
    20145226夏艺华 《Java程序设计》第9周学习总结
    20145226夏艺华 《Java程序设计》第8周学习总结
  • 原文地址:https://www.cnblogs.com/abclzr/p/5962258.html
Copyright © 2011-2022 走看看