[JSOI 2015] the greatest common divisor

Description

Exam link (recently \ (\ text {bzoj} \ ) maintenance can not go up, the link gave Los Valley ...

A given length of \ (n-\) a sequence of positive integers \ (A \) . Defining a consecutive sub-segments \ ([L, R & lt] \) , which is right \ [\ left (\ gcd \ limits_ {l \ leq i \ leq r} ^ {} A_i \ right) \ times (r-l +1) \]

Praying segment maximum weight is how much.

\ (1 \ leq n \ leq 100000,1 \ leq A_i \ leq 10 ^ {12} \)

Solution

Obvious to a right end point is determined, the values of all points in the left, a whole segment of \ (\ GCD \) species is not more than the number \ (\ log A_i \) a.

We just able to save this \ (\ log A_i \) number of conventions and record the leftmost point to the corresponding left.

Time complexity is \ (O (n-\ ^ 2 log A_i) \) .

Code

#include <bits/stdc++.h>
#define ll long long
#define pli pair<ll, int>
#define fr first
#define sc second
#define pb push_back
using namespace std;
const int N = 100000+5;

int n, cnt;
ll a[N], ans;
vector<pli > g[N];

ll gcd(ll a, ll b) {return b ? gcd(b, a%b) : a; }
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    for (int i = 1; i <= n; i++) {
        cnt = 0;
        for (int j = 0, sz = g[i-1].size(); j < sz; j++) {
            pli x = g[i-1][j];
            ll t = gcd(a[i], x.fr);
            ans = max(ans, t*(i-x.sc+1));
            if (!cnt || t != g[i][cnt-1].fr) g[i].pb(pli(t, x.sc));
            ++cnt;
        }
        pli x = pli(a[i], i);
        ll t = gcd(a[i], x.fr);
        ans = max(ans, t*(i-x.sc+1));
        if (!cnt || t != g[i][cnt-1].fr) g[i].pb(pli(t, x.sc));
    }
    printf("%lld\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/NaVi-Awson/p/11575640.html