• 计蒜客 蒜头君的数轴


    不考虑某个区间,其他区间必须距离相等,也就是要划分为距离为最大公约数。

    那么如何快速求解任意$n-1$个区间的最大公约数?用l[i]表示前i个数的最大公约数,r[i]表示后$(n-i)$个区间的最大公倍数,删除区间i之后剩余的$n-1$个区间的最大公约数就是$gcd(l[i-1], r[i+1])$


    AC代码

    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int maxn = 100000 + 5;
    int x[maxn], dis[maxn];
    int l[maxn], r[maxn];
    
    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a%b);
    }
    
    int main() {
        int n;
        while(scanf("%d", &n) == 1) {
            for(int i = 0; i < n; i++) {
                scanf("%d", &x[i]);
            }
            if(n <= 3) {
                printf("0
    ");
                continue;
            }
            sort(x, x+n);
            LL sum_dis = 0;
            for(int i = 1; i < n; i++) {
                dis[i-1] = x[i] - x[i-1];
                sum_dis += dis[i-1];
            }
            LL ans = 1e18;
            n -= 1;
            l[0] = dis[0];
            for(int i = 1; i < n; i++) {
                l[i] = gcd(l[i-1], dis[i]);
            }
            r[n-1] = dis[n-1];
            for(int i = n-2; i >= 0; i--) {
                r[i] = gcd(r[i+1], dis[i]);
            }
            //删除最左端距离
            ans = min(ans, (sum_dis-dis[0])/r[1] - (n-1));
            //删除最右端距离
            ans = min(ans, (sum_dis-dis[n-1])/l[n-2] - (n-1));
            //删除[1,n-2]
            for(int i = 1; i <= n-2; i++) {
                ans = min(ans, (sum_dis - dis[i])/gcd(l[i-1], r[i+1]) - (n-1));
            }
            printf("%lld
    ", ans);
        } 
        return 0;
    }

    如有不当之处欢迎指出!

  • 相关阅读:
    PERL 学习
    javascript
    Netfilter
    PHP内核探索
    Linux内存管理学习笔记 转
    使用mysqladmin ext 了解MySQL运行状态 转
    在ArcGIS Desktop中进行三参数或七参数精确投影转换
    AE 栅格图分级渲染
    ArcEngine标注和注记
    ArcGIS Engine 线段绘制
  • 原文地址:https://www.cnblogs.com/flyawayl/p/8659044.html
Copyright © 2020-2023  润新知