bzoj4488:[Jsoi2015]最大公约数

Pre

细节!!!

又双叒叕错在了一些简单的地方。

测试的时候发现有两个点会\(WA\)掉,最后发现不能再循环的开头更新答案,因为最后一次的答案无法计入统计。

Solution

考虑到\(GCD\)可以整个区间的\(GCD\)当成一个数来进行处理,考虑\(GCD\)的转折点,就是我的数组里面的数,这样的话可以维护出每一个转折点到当前的点的\(GCD\)的值,可以动态更新,所以最后边更新边统计答案。

Code

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define xx first
#define yy second

using namespace std;

const ll N = 1000000 + 5;
ll info[N], ans, g[N];
ll n, f[N], top = 0;

ll gcd (ll m, ll n) {
    return n == 0 ? m : gcd (n, m % n);
}

int main () {
    cin >> n;
    for (ll i = 1; i <= n; ++i) {
        cin >> info[i];
    }
    ans = info[1];
    for (ll i = 1; i <= n; ++i) {
        ++top;
        f[top] = i;
        g[top] = info[i];
        for (ll j = top - 1; j >= 1; --j) {
            g[j] = gcd (g[j], g[j + 1]);
            ans = max (ans, 1LL * (i - f[j] + 1) * g[j]);
        }
        ll tmp = 0;
        for (ll j = 1; j <= top;) {
            ++tmp;
            f[tmp] = f[j];
            g[tmp] = g[j];
            while (j <= top && g[j] == g[tmp]) {
                j++;
            }
        }
        top = tmp;
        for (ll j = 1; j <= top; ++j) {
            ans = max (ans, 1LL * (i - f[j] + 1) * g[j]);//在这里统计答案
        }
    }
    cout << ans << endl;
    return 0;
}

Conclusion

细节有一点多,应该更加注意一些。

上一篇:BZOJ 4488: [Jsoi2015]最大公约数


下一篇:【BZOJ4487】[JSOI2015]染色问题(容斥)