大力辛普森积分

精度什么的搞了我好久…

学到了Simpson的一个trick

深度开11,eps开1e-4.跑的比有些扫描线还快…

CODE

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 205;
const double eps = 1e-10;
inline double sqr(double x) { return x*x; }
inline int dcmp(double x) {
return x < -eps ? -1 : x < eps ? 0 : 1;
}
int n, tot, st, ed;
struct node {
double x, l, r, y, v;
node(){}
node(double x, double l, double r, double y, double v):x(x), l(l), r(r), y(y), v(v){}
inline double L()const { return y < 0 ? x + y : x; }
inline double R()const { return y > 0 ? x + y : x; }
inline bool operator <(const node &o)const {
return L() == o.L() ? R() < o.R() : L() < o.L();
}
}arr[MAXN];
struct NODE {
double l, r;
NODE(){}
NODE(double l, double r):l(l), r(r){}
inline bool operator <(const NODE &o)const {
return l == o.l ? r < o.r : l < o.l;
}
}seq[MAXN];
inline double f(double x) {
int cur = 0;
for(int i = st; i <= ed; ++i)
if(arr[i].L() < x && x < arr[i].R())
seq[++cur] = NODE( arr[i].l + (x-arr[i].x)/arr[i].y * (arr[i].v-arr[i].l),
arr[i].r + (x-arr[i].x)/arr[i].y * (arr[i].v-arr[i].r) );
sort(seq + 1, seq + cur + 1);
double re = 0;
for(int i = 1, j; i <= cur; i = j) { //求并集
double L = seq[i].l, R = seq[i].r;
for(j = i+1; j <= cur; ++j)
if(dcmp(seq[j].l-R) > 0) break;
else R = max(R, seq[j].r);
re += R-L;
}
return re;
}
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-4) return g; //Simpson积分套路 : 加一个深度
else return Simpson(L, M1, M, fL, fM1, fM, dep+1) + Simpson(M, M2, R, fM, fM2, fR, dep+1);
}
int main() {
scanf("%d", &n);
double a, b, c, x, y, z;
for(int i = 1; i <= n; ++i) {
scanf("%lf%lf%lf%lf%lf%lf", &a, &x, &b, &y, &c, &z);
if(b < a || (b == a && y < x)) swap(a, b), swap(x, y); //排一下序
if(c < a || (c == a && z < x)) swap(a, c), swap(x, z);
if(c < b || (c == b && z < y)) swap(b, c), swap(y, z);
if(a == b)
arr[++tot] = node(b, x, y, c-b, z);
else if(b == c)
arr[++tot] = node(b, y, z, a-b, x);
else { //把三角形竖直切开拆成两个,方便后面计算
double tmp = x + (b-a)/(c-a) * (z-x);
arr[++tot] = node(b, min(tmp, y), max(tmp, y), a-b, x);
arr[++tot] = node(b, min(tmp, y), max(tmp, y), c-b, z);
}
}
sort(arr + 1, arr + tot + 1);
double ans = 0;
for(int i = 1, j; i <= tot; i = j) {
double L = arr[i].L(), R = arr[i].R();
for(j = i+1; j <= tot; ++j)
if(dcmp(arr[j].L()-R) > 0) break;
else R = max(R, arr[j].R());
double M = (L + R) / 2;
st = i, ed = j-1;
double fL = f(L), fM = f(M), fR = f(R);
ans += Simpson(L, M, R, fL, fM, fR, 0);
}
printf("%.2f\n", ans);
}

BZOJ 1845: [Cqoi2005] 三角形面积并 (辛普森积分)的更多相关文章

  1. bzoj 1845: [Cqoi2005] 三角形面积并 扫描线

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 848  Solved: 206[Submit][Statu ...

  2. BZOJ 1845: [Cqoi2005] 三角形面积并 [计算几何 扫描线]

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 1151  Solved: 313[Submit][Stat ...

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

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

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

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

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

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

  6. BZOJ 2178: 圆的面积并 (辛普森积分)

    code #include <set> #include <cmath> #include <cstdio> #include <cstring> #i ...

  7. CQOI2005 三角形面积并 和 POJ1177 Picture

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 1664  Solved: 443[Submit][Stat ...

  8. [CQOI2005]三角形面积并

    [CQOI2005]三角形面积并 题目大意: 求\(n(n\le100)\)个三角形的面积并. 思路: 自适应辛普森法,玄学卡精度可过. 源代码: #include<cmath> #inc ...

  9. 【BZOJ1845】[Cqoi2005] 三角形面积并 几何+扫描线

    [BZOJ1845][Cqoi2005] 三角形面积并 Description 给出n个三角形,求它们并的面积. Input 第一行为n(N < = 100), 即三角形的个数 以下n行,每行6 ...

随机推荐

  1. [转帖]2019-03-26 发布 深入理解 MySQL ——锁、事务与并发控制

    深入理解 MySQL ——锁.事务与并发控制 https://segmentfault.com/a/1190000018658828 太长了 没看完.. 数据库 并发  mysql 639 次阅读   ...

  2. MySQL添加、修改、撤销用户数据库操作权限的一些记录

    查看MYSQL数据库中所有用户 SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user; ...

  3. Flask Bug记录之JinJa2.exceptions.UndefinedError: 'sqlite3.Row object' has no attribute 'get'

    源码 py文件定义db的工厂函数如下 def get_db(): if "db" not in g: g.db = sqlite3.connect( current_app.con ...

  4. oracle多表关联删除的两种方法

    oracle多表关联删除的两种方法 第一种使用exists方法 delete from tableA where exits ( select 1 from tableB Where tableA.i ...

  5. JAVA对存储过程的调用方法(本文源于网络)

    博客分类: java java存储过程sql  一:Java如何实现对存储过程的调用:   A:不带输出参数的   ---------------不带输出参数的-------------------- ...

  6. Java浅拷贝与深拷贝(思维导图)

    图1 拷贝思维导图(点击查看图片) 1,拷贝 有两个相同属性的对象A和B,A拥有初始化值,将其值拷贝到B中,使得B拥有与A“相同”数据的属性!注意这里的相同我有加双引号! 相同可能表示这么几个意思:① ...

  7. oracle解锁oracle默认用户scott

    oracle中存在一个默认的用户scott,密码为tiger,当在安装oracle时,若未给该账户解锁,则登录该用户时, 会提示被锁定. 如何通过sqlplus命令为scott解锁: 1.C:> ...

  8. go语言入门(7)面向对象编程

    1,概述     对于面向对象编程的支持Go 语言设计得非常简洁而优雅.因为, Go语言并没有沿袭传统面向对象编程中的诸多概念,比如继承(不支持继承,尽管匿名字段的内存布局和行为类似继承,但它并不是继 ...

  9. java 日期。时间

    友情链接: https://www.cnblogs.com/wanson/articles/10818955.html

  10. Image Processing and Analysis_8_Edge Detection:The Design and Use of Steerable Filters——1991

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...