zoukankan      html  css  js  c++  java
  • NOI模拟题6 Problem C: Circle

    Solution

    首先这个矩阵, 很明显的就是Vandermonde矩阵. 我们有公式:

    [|F_n| = prod_{1 le j < i le n} (a_i - a_j) ]

    套圈的半径, 显然就是最小圆覆盖问题.

    考虑到数据范围比较大, 我们直接做肯定是不行的. 这时候就涉及到一个神奇的东西:

    我们知道假如行列式的某两行相同, 则该行列式的值为(0). 考虑这道题, 我们发现它生成数据的方式非常奇怪, 假设生成(x)组询问, 则所有询问两两不相同的概率为

    [prod_{k = n}^{n - x + 1} frac k n ]

    这个概率会迅速地下降, 因此期望不需要太多的次数, 行列式的值就会变为(0)...

    真是有意思...

    #include <cstdio>
    #include <cctype>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
     
    using namespace std;
    namespace Zeonfai
    {
        inline int getInt()
        {
            int a = 0, sgn = 1; char c;
            while (! isdigit(c = getchar())) if (c == '-') sgn *= -1;
            while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
            return a * sgn;
        }
    }
    const int N = (int)1e5, M = (int)1e5, MOD = (int)1e9 + 7;
    struct point
    {
        double x, y;
        inline point friend operator -(const point &a, const point &b) { point res; res.x = a.x - b.x; res.y = a.y - b.y; return res; }
        inline double friend operator *(const point &a, const point &b) { return a.x * b.y - a.y * b.x; }
    }p[N + 1];
    double r[M + 1];
    int L[M + 1], R[M + 1];
    inline double sqr(double a) { return a * a; }
    inline double getDistance(point a, point b) { return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); }
    inline point getCentre(point a, point b, point c)
    {
        point ret;
        double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1 * a1 + b1 * b1) / 2;
        double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2 * a2 + b2 * b2) / 2;
        double d = a1 * b2 - a2 * b1;
        ret.x = a.x + (c1 * b2 - c2 * b1) / d;
        ret.y = a.y + (a1 * c2 - a2 * c1) / d;
        return ret;
    }
    int main()
    {
     
    #ifndef ONLINE_JUDGE
     
        freopen("circle.in", "r", stdin);
        freopen("circle.out", "w", stdout);
     
    #endif
     
        using namespace Zeonfai;
        int n = getInt();
        for (int i = 1; i <= n; ++ i) p[i].x = getInt(), p[i].y = getInt();
        int m = getInt();
        int ans = 1;
        for (int i = 1; i <= m; ++ i)
        {
            L[i] = getInt(), R[i] = getInt();
            if (! ans) { printf("%lld
    ", (long long)L[i] * R[i]); continue; }
            point cen = p[L[i]]; r[i] = 0;
            for (int j = L[i] + 1; j <= R[i]; ++ j) if (getDistance(p[j], cen) > r[i])
            {
                cen = p[j]; r[i] = 0;
                for (int k = L[i]; k < j; ++ k) if (getDistance(p[k], cen) > r[i])
                {
                    cen.x = (p[j].x + p[k].x) / 2; cen.y = (p[j].y + p[k].y) / 2;
                    r[i] = getDistance(p[j], cen);
                    for (int l = L[i]; l < k; ++ l) if (getDistance(p[l], cen) > r[i])
                    {
                        if ((p[k] - p[j]) * (p[l] - p[j]) == 0)
                        {
                            cen.x = (p[j].x + p[l].x) / 2; cen.y = (p[j].y + p[l].y) / 2;
                            r[i] = getDistance(p[l], cen);
                        }
                        else cen = getCentre(p[j], p[k], p[l]), r[i] = getDistance(p[l], cen);
                    }
                }
            }
            for (int j = 1; j < i; ++ j) ans = (long long)ans * ((long long)r[i] - (long long)r[j] + MOD) % MOD;
            printf("%lld
    ", (long long)ans + L[i] * R[i]);
        }
    
  • 相关阅读:
    高斯消元模板
    hdu4210 Sudominoku (dfs)
    Linux 下eclipse cpp配置libvlc环境
    PaddleDetection 导出PPYOLO 类型模型时报错AssertionError: Bad argument number for Assign: 2, expecting 3 解决记录
    qt 记录调用setStyleSheet设置样式后不生效问题
    ubuntu 在docker中使用gpu,安装nvidiacontainerruntime
    Linux 下使用libvlc 播放视频 C++
    QT 通过installEventFilter实现监控控件鼠标移入移出效果
    qt 记录某些控件 debug样式正常, release 样式不正常问题
    QT 记录一次窗口构造函数中访问UI控件报错问题
  • 原文地址:https://www.cnblogs.com/ZeonfaiHo/p/7598687.html
Copyright © 2011-2022 走看看