Magical GCD
Magical GCD
CERC 2013。
思路
维护区间GCD考虑ST表维护。考虑对于固定左端点开始的序列,它的GCD是单调不增的,那么对于固定的一个GCD值,序列长度越长积自然越大,因此考虑枚举左端点,查找对于它的每个GCD的最大\(F\),二分查找GCD的右边界。由于需要遍历所有点作为左端点,每次的GCD的值最多有\(\log\)个,加上二分右边界,因此复杂度为\(O(n\log^2 n)\)。
代码
inline int GCD(int l,int r)
{
int len = log2(r - l + 1);
return __gcd(gcd[l][len],gcd[r - (1 << len) + 1][len]);
}
inline int find(int i,int l,int r,int val)
{
int res;
while(l <= r){
int mid = (l + r) >> 1;
if(GCD(i,mid) == val) res = mid,l = mid + 1;
else r = mid - 1;
}
return res;
}
signed main()
{
T = read();
while(T--)
{
n = read();
for(int i = 1;i <= n;i++) gcd[i][0] = a[i] = read();
for(int k = 1;k <= 17;k++){
for(int i = 1;i + (1 << k) - 1 <= n;i++){
gcd[i][k] = __gcd(gcd[i][k - 1],gcd[i + (1 << (k - 1))][k - 1]);
}
}
ans = 0;
for(int i = 1;i <= n;i++){
for(int l = i,r = 0;l <= n;l = r + 1){
r = find(i,l,n,GCD(i,l));
ans = max(ans,(r - i + 1) * GCD(i,r));
}
}
write(ans),putchar('\n');
}
return 0;
}
艰难困苦,玉汝于成

浙公网安备 33010602011771号