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

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

原文地址:https://www.cnblogs.com/ChiTongZ/p/11147007.html