BZOJ 4052: [Cerc2013]Magical GCD

时间:2022-01-30 19:42:05

以一个数字开头的子序列的gcd种类不会超过logn种,因此去找相同gcd最长的位置,更新一下答案,复杂度O(nlogn^2)

 #include<cstdio>
#include<algorithm>
#include<cmath>
#define N 300010
using namespace std;
int n,i,Log[N],j,l,left,right,mid;
long long s[N][],ans;
long long gcd(long long a,long long b)
{
if (b==) return a;
return gcd(b,a%b);
}
long long Q(int l,int r)
{
int k=Log[r-l+];
return gcd(s[l][k],s[r-(<<k)+][k]);
}
int main()
{
int test;
scanf("%d",&test);
while (test--)
{
ans=;
scanf("%d",&n);
for (i=;i<=n;i++)
scanf("%lld",&s[i][]);
for (i=;i<=n;i++)
Log[i]=log2(i);
for (i=n;i>=;i--)
for (j=;j<=Log[n];j++)
s[i][j]=gcd(s[i][j-],s[i+(<<(j-))][j-]); for (i=;i<=n;i++)
{
l=i;
while (l<=n)
{
left=l;
right=n;
while (left<=right)
{
mid=(left+right)>>;
if (Q(i,mid)==Q(i,l))
left=mid+;
else
right=mid-;
}
l=right+;
ans=max(ans,(right-i+)*Q(i,right));
}
}
printf("%lld\n",ans);
}
}