UVA - 1642 Magical GCD 数学

                              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;
}

 

posted @ 2016-04-03 13:55  meekyan  阅读(442)  评论(0编辑  收藏  举报