思路:容易发现以某个位置
\(i\)为结尾所有后缀的
\(gcd\)个数不超过
\(log(a[i])\)。
(怎么发现?将数写成质因子幂次乘积的形式,然后
\(gcd\)每次减小一个质因子,最多减少
\(log\)次)然后就可以用
\(map\)维护每个
\(gcd\)的最左端端点。
代码:
#pragma GCC optimize(2)#pragma GCC optimize(3)#pragma GCC optimize(4)#include using namespace std;#define fi first#define se second#define pi acos(-1.0)#define LL long long//#define mp make_pair#define pb push_back#define ls rt<<1, l, m#define rs rt<<1|1, m+1, r#define ULL unsigned LL#define pll pair #define pii pair #define piii pair #define mem(a, b) memset(a, b, sizeof(a))#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);//headconst int N = 1e5 + 5;LL a[N];map mp, _p;int n; int main() { scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]); LL ans = 0; for (int i = 1; i <= n; ++i) { ans = max(ans, a[i]); for (map ::iterator it = mp.begin(); it != mp.end(); ++it) { LL g = __gcd(a[i], (*it).fi); ans = max(ans, g*(i-(*it).se+1)); if(_p.find(g) == _p.end()) _p[g] = (*it).se; } if(_p.find(a[i]) == _p.end()) _p[a[i]] = i; mp = _p; _p.clear(); } printf("%lld\n", ans); return 0;}