code

#include <set>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
const double Pi = acos(-1.0);
const double eps = 1e-12;
const double INF = 1e12;
inline int dcmp(double x) {
if(x <= eps && x >= -eps) return 0;
return x > 0 ? 1 : -1;
}
inline double sqr(double x) { return x*x; }
struct Vector {
double x, y;
inline Vector(double _x=0, double _y=0): x(_x), y(_y){}
inline Vector operator *(const double &k)const { return Vector(x*k, y*k) ;}
inline Vector operator +(const Vector &t)const { return Vector(x+t.x, y+t.y); }
inline Vector operator -(const Vector &t)const { return Vector(x-t.x, y-t.y); }
};
struct Point {
double x, y;
inline Point(double _x=0, double _y=0): x(_x), y(_y){}
inline Vector operator -(const Point &t)const { return Vector(x - t.x, y - t.y); }
inline Point operator +(const Vector &t)const { return Point(x + t.x, y + t.y); }
inline double dist(const Point &t) { return sqrt(sqr(x-t.x) + sqr(y-t.y)); }
inline double dist(const double &a, const double &b) { return sqrt(sqr(x-a) + sqr(y-b)); }
};
struct Line {
Point p;
Vector v;
double ang;
inline Line(Point _p=Point(0, 0), Vector _v=Vector(0, 0)): p(_p), v(_v), ang(atan2(v.y, v.x)){}
inline bool operator <(const Line &t)const { return ang < t.ang; }
};
struct Circle {
Point o; double r;
inline Circle(Point _o=Point(0, 0), double _r=0): o(_o), r(_r){}
};
inline double Cross(const Vector &a, const Vector &b) { return a.x*b.y - a.y*b.x; }
inline bool Turn_Left(const Point &a, const Point &b, const Point &c) { return dcmp(Cross(b-a, c-a)) > 0; }
inline bool On_Left(const Line &a, const Point &b) { return dcmp(Cross(a.v, b-a.p)) >= 0; }
inline Point GLI(const Point &P, const Vector &v, const Point &Q, const Vector &w) { //Intersection
Vector u = Q - P;
double k = Cross(u, w) / Cross(v, w);
return P + v*k;
}
inline double Angle_C(const double &a, const double &b, const double &c) { //Triangle's 3 edges
return acos((sqr(a)+sqr(b)-sqr(c))/(2*a*b));
}
inline double Tri_S(const Point &a, const Point &b, const Point &c) { return fabs(Cross(b-a, c-a))/2; }
inline Point rotate(const double &x, const double &y, const double °ree) {
return Point(x*cos(degree)-y*sin(degree), x*sin(degree)+y*cos(degree));
}
int n; Circle cir[MAXN], tmp[MAXN];
inline bool cmp(const Circle &a, const Circle &b) {
return a.o.x-a.r < b.o.x-b.r;
//stO Orz -.- >.< xp XD qwq QAQ ToT QwQ QuQ :-) )-: o-: qx TnT
}
inline bool cmp2(const Circle &a, const Circle &b) {
return a.r > b.r;
}
inline bool chk(const Circle &a, const Circle &b) {
return sqr(a.o.x-b.o.x) + sqr(a.o.y-b.o.y) <= sqr(a.r-b.r);
}
inline void Pre_work() {
sort(cir + 1, cir + n + 1, cmp2);
int cnt = 0;
for(int i = 1; i <= n; ++i) if(cir[i].r) {
bool flg = 1;
for(int j = 1; j <= cnt; ++j)
if(chk(cir[i], tmp[j])) { flg = 0; break; }
if(flg) tmp[++cnt] = cir[i];
}
n = cnt;
for(int i = 1; i <= n; ++i) cir[i] = tmp[i];
sort(cir + 1, cir + n + 1, cmp);
}
int st, ed, tot;
pair<double, double>intervals[MAXN<<1]; inline void getCircleIntersection(const Circle &O, const double &x) {
double len = sqrt(sqr(O.r) - sqr(x-O.o.x));
intervals[++tot] = make_pair(O.o.y-len, O.o.y+len);
} inline double f(double x) {
tot = 0;
for(int i = st; i <= ed; ++i)
if(x < cir[i].o.x+cir[i].r && x > cir[i].o.x-cir[i].r)
getCircleIntersection(cir[i], x);
sort(intervals + 1, intervals + tot + 1);
double L = -INF, R = -INF, res = 0;
for(int i = 1; i <= tot; ++i)
if(intervals[i].first > R)
res += R - L, L = intervals[i].first, R = intervals[i].second;
else R = max(R, intervals[i].second);
return res + (R - L);
}
inline double Simpson(double L, double M, double R, double fL, double fM, double fR, int dep) {
double M1 = (L + M) / 2, M2 = (M + R) / 2;
double fM1 = f(M1), fM2 = f(M2);
double g1 = (M-L) * (fL + 4*fM1 + fM) / 6,
g2 = (R-M) * (fM + 4*fM2 + fR) / 6,
g = (R-L) * (fL + 4*fM + fR) / 6;
if(dep > 11 && fabs(g-g1-g2) < 1e-10) return g;
else return Simpson(L, M1, M, fL, fM1, fM, dep+1) + Simpson(M, M2, R, fM, fM2, fR, dep+1);
}
inline double solve() {
double ans = 0;
for(int i = 1, j; i <= n; ++i) {
double L = cir[i].o.x - cir[i].r, R = cir[i].o.x + cir[i].r;
for(j = i+1; j <= n; ++j)
if(cir[j].o.x - cir[j].r > R) break;
else R = max(R, cir[j].o.x + cir[j].r);
double M = (L + R) / 2;
st = i, ed = i = j-1;
double fL = f(L), fM = f(M), fR = f(R);
ans += Simpson(L, M, R, fL, fM, fR, 0);
}
return ans;
}
int main () {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%lf%lf%lf", &cir[i].o.x, &cir[i].o.y, &cir[i].r);
Pre_work();
printf("%.3f\n", solve());
}

BZOJ 2178: 圆的面积并 (辛普森积分)的更多相关文章

  1. BZOJ 2178: 圆的面积并 [辛普森积分 区间并]

    2178: 圆的面积并 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1740  Solved: 450[Submit][Status][Discus ...

  2. bzoj 2178 圆的面积并 —— 辛普森积分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178 先看到这篇博客:https://www.cnblogs.com/heisenberg- ...

  3. bzoj 2178 圆的面积并——辛普森积分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178 把包含的圆去掉.横坐标不相交的一段一段圆分开算.算辛普森的时候预处理 f( ) ,比如 ...

  4. BZOJ 2178 圆的面积并 ——Simpson积分

    [题目分析] 史上最良心样例,史上最难调样例. Simpson积分硬上. 听说用long double 精度1e-10才能过. 但是double+1e-6居然过了. [代码] #include < ...

  5. [BZOJ 2178] 圆的面积并 【Simpson积分】

    题目链接:BZOJ - 2178 题目分析 用Simpson积分,将圆按照 x 坐标分成连续的一些段,分别用 Simpson 求. 注意:1)Eps要设成 1e-13  2)要去掉被其他圆包含的圆. ...

  6. BZOJ 1845: [Cqoi2005] 三角形面积并 (辛普森积分)

    大力辛普森积分 精度什么的搞了我好久- 学到了Simpson的一个trick 深度开11,eps开1e-4.跑的比有些扫描线还快- CODE #include <bits/stdc++.h> ...

  7. bzoj 2178 圆的面积并【simpson积分】

    直接套simpson,f可以直接把圆排序后扫一遍所有圆,这样维护一个区间就可以避免空段. 然而一定要去掉被其他圆完全覆盖的圆,否则会TLE #include<iostream> #incl ...

  8. 【BZOJ】2178: 圆的面积并

    http://www.lydsy.com/JudgeOnline/problem.php?id=2178 题意:给出n<=1000个圆,求这些圆的面积并 #include <cstdio& ...

  9. BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]

    1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1070  Solved: 596[Submit][Status] ...

随机推荐

  1. RxJava基本使用

    更多文章请点击链接:http://77blogs.com/?p=162 转载请标明出处:https://www.cnblogs.com/tangZH/p/12088300.html,http://77 ...

  2. 将一个整数数组先按照因子数量排序,再按照数字大小排序,输出第k个数

    同小米OJ比赛题:现在有 n 个数,需要用因子个数的多少进行排序,因子个数多的排在后面,因子个数少的排在前面,如果因子个数相同那么就比较这个数的大小,数大的放在后面,数小的放在前面.现在让你说出排序之 ...

  3. SQL SERVER 字符串函数 STRING_SPLIT()

    定义: STRING_SPLIT()函数根据指定的分隔符将字符串拆分为子字符串行. ※STRING_SPLIT 要求兼容性级别至少为 130. (即SSMS 2016及以上版本) ※级别低于 130 ...

  4. Problems to be upsolved

    Donation 官方题解尚未看懂. comet oj contest15 双11特惠hard Mobitel Small Multiple 题解 为什么可以如此缩点? Candy Retributi ...

  5. cmake 简单build和删除

    mkdir build cd build cmake .. make

  6. docker部署redis

    镜像获取 docker pull redis:4.0 ##当前最新版本 docker images 启动 docker run --name redis-huiyuan -p : -v $PWD/da ...

  7. StoneTab标签页CAD插件 3.2.6

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  8. git 分布式版本控制

    一.git版本控制 管理文件夹 安装省略 1. 进入要管理的文件夹 2. 初始化 (提名) 3. 管理 4. 生成版本 对应的命令: # 进入文件夹以后 右击选git bash here #初始化 g ...

  9. api校验

    服务端代码: import hashlib import time KEY = 'RTYUIFGHJKVBNM' def gen_key(ctime): md5 = hashlib.md5() key ...

  10. .NET webapi 的单元测试

    public abstract class MirAPIUnitTestCommon { public abstract string GetBaseAddress(); /// <summar ...