题解SP8073【CIRU - 円の労働組合のエリア】

トピックリンク

ソリューション円とエリア

タイトル効果:指定された\(N- \)のラウンドは、\(N- \のLeq 1000年\)円の面積を見つけ、

アダプティブ・シンプソン


円形領域の我々は良いを見つけることが、我々ができ\(O(nlogn)\)\(N- \)我々が使用できるように、線分および\(fは(X)\)直線を表す\(X = X \)各円と接線の、我々は見つける\ - (\ INT _ {\ \ inftyの} ^ {\ inftyの} F(X); DX \) に

シンプソンの直接適応はなく、単純なアルゴリズムと、そのような比較的まばらな分布のラウンドのように簡単に揚げ精度(、場合は、第一層シンプソンアルゴリズムを取ることに注意してください)\(5 \ポイントが全てです(0 \)\ GGに、あなたは、セグメンテーション・シンプソンを行うことができます)

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
using namespace std;
const int maxn = 1024;
double eps = 1e-4;
struct Seg{
    double l,r;
    bool operator < (const Seg &rhs)const{return l < rhs.l;}
}seg[maxn];
struct Round{
    double x,y,r;
}val[maxn];
int n;
map<double,double> mp; 
inline double f(double x){
    if(mp[x])return mp[x];
    static Seg seg[maxn];
    int tot = 0;
    for(int i = 1;i <= n;i++){
        double deltay = val[i].r * val[i].r - (val[i].x - x) * (val[i].x - x);
        if(deltay <= eps)continue;
        deltay = sqrt(deltay);
        seg[++tot] = Seg{val[i].y - deltay,val[i].y + deltay};
    }
    sort(seg + 1,seg + 1 + tot);
    double res = 0,last = -1e9;
    for(int i = 1;i <= tot;i++){
        const Seg &now = seg[i];
        if(now.l > last)res += now.r - now.l,last = now.r;
        else if(now.r > last)res += now.r - last,last = now.r;
    }
    return mp[x] = res;
}
inline double simpson(double l,double r){
    double mid = (l + r) / 2.0;
    return (r - l) * (f(l) + f(mid) * 4.0 + f(r)) / 6.0;
}
inline double solve(double l,double r,double now,double eps){
    double mid = (l + r) / 2.0,L = simpson(l,mid),R = simpson(mid,r);
    if(fabs(L + R - now) < eps)return L + R;
    return solve(l,mid,L,eps / 2) + solve(mid,r,R,eps / 2);
}
double l = 1e9,r = -1e9,ans,last = -1e9;
int main(){
    ios::sync_with_stdio(false);
    cin >> n;
    for(int i = 1;i <= n;i++){
        cin >> val[i].x >> val[i].y >> val[i].r;
        seg[i] = Seg{val[i].x - val[i].r,val[i].x + val[i].r};
        l = min(l,val[i].x - val[i].r);
        r = max(r,val[i].x + val[i].r);
    }
    sort(seg + 1,seg+ 1 + n);
    for(int i = 1;i <= n;i++){
        const Seg &now = seg[i];
        if(now.l > last)ans += solve(now.l,now.r,simpson(now.l,now.r),eps),last = now.r;
        else if(now.r > last)ans += solve(last,now.r,simpson(now.l,now.r),eps),last = now.r;
    }
    cout << setiosflags(ios::fixed) << setprecision(3) << ans << '\n';
    return 0;
}

おすすめ

転載: www.cnblogs.com/colazcy/p/12061397.html