• UVA


                                  Magical GCD

    The Magical GCD of a nonempty sequence of positive integers is defined as the product of its length
    and the greatest common divisor of all its elements.
    Given a sequence (a1, . . . , an), find the largest possible Magical GCD of its connected subsequence.
    Input
    The first line of input contains the number of test cases T. The descriptions of the test cases follow:
    The description of each test case starts with a line containing a single integer n, 1 ≤ n ≤ 100000.
    The next line contains the sequence a1, a2, . . . , an, 1 ≤ ai ≤ 1012
    .
    Output
    For each test case output one line containing a single integer: the largest Magical GCD of a connected
    subsequence of the input sequence.
    Sample Input
    1
    5
    30 60 20 20 20
    Sample Output
    80

    题意:

      给你N个数,求一个连续子序列,使得该序列中所有的最大公约数与序列长度的乘积最大

    题解:

      首先明确的做法是:枚举右端点,然后找到一个答案最大的左端点更新答案

      那么如何找到这个最大的左端点,

      假设我们求出了前i个数每个j(1<=j<=i) 的匹配的最优左端点,且gcd值,对应pos位置值已知,

      那么我们可以根据gcd在非递增下,去更新这些gcd值和gcd值相同情况下 最左的左端点

      这样的复杂度是nlogn的,

      不同gcd至少相差2倍,我们就可以知道它是log的了

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int N = 1e5+7, M = 30005, mod = 1e9+7, inf = 0x3f3f3f3f;
    typedef long long ll;
    //不同为1,相同为0
    
    int T,n;
    ll a[N];
    ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); }
    vector<pair<ll,int > > v;
    int main() {
        scanf("%d",&T);
        while(T--) {
            scanf("%d",&n);
            v.clear();
            ll ans = 0;
            for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
            for(int j=1;j<=n;j++) {
                v.push_back(make_pair(0,j));
                int k = v.size();
                for(int i=0;i<k;i++) {
                    v[i].first = (gcd(v[i].first,a[j]));
                }
                sort(v.begin(),v.end());
                vector<pair<ll,int > > now;
                for(int i=0;i<v.size();i++) {
                    if(i == 0 || v[i-1].first != v[i].first) {
                        now.push_back(v[i]);
                        ans = max(ans, 1ll*v[i].first*(j - v[i].second+1));
                    }
                }
                v = now;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    搭建kafka集群
    fluentd 安装、配置、使用介绍
    彻底解决 es 的 unassigned shards 症状
    nginx 反向代理时丢失端口的解决方案
    kubernetes的imagePullSecrets如何生成及使用
    创建MySQL数据库账号
    Linux中查找文件
    Linux快速访问多个目录
    Django查询数据库返回字典dict数据
    linux 将压缩包复制到另外一个文件夹下面
  • 原文地址:https://www.cnblogs.com/zxhl/p/5349764.html
Copyright © 2020-2023  润新知