BZOJ 4052: [Cerc2013]Magical GCD

题意:给出一个长度在 100 000 以内的正整数序列,大小不超过 10^12。 求一个连续子序列,使得在所有的连续子序列中,它们的GCD值乘以它们的长度最大。

gcd每次至少会下降2,所以不同的gcd值个数最多为log2(10^12),我们枚举连续子序列的终点j,则中间肯定会有很多点对i,i+1,gcd(i,j)=gcd(i+1,j).维护一个单调栈,发现这种情况删除即可。

#include
#include
#include
#include
#include
using namespace std;
const int maxn=100000+10;
long long a[maxn],ans;
struct node
{
  int p;
  long long v;
}st[maxn],hm[maxn];
int n,T,top;
int main()
{
  //freopen("4052.in","r",stdin);
  //freopen("4052.out","w",stdout);
  scanf("%d",&T);
  while(T--)
  {
    scanf("%d",&n);
    top=0;ans=0;
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
    {
      st[++top]=(node){i,a[i]};
      for(int j=1;j<=top;j++) st[j].v=__gcd(st[j].v,a[i]);
      int tot=0;
      for(int j=1;j<=top;j++)
        if(st[j].v>st[j-1].v)
         hm[++tot]=st[j];
      top=tot;
      for(int j=1;j<=tot;j++) st[j]=hm[j];
      for(int j=1;j<=tot;j++)
        ans=max(ans,st[j].v*(long long)(i-st[j].p+1));
    }
    printf("%lld\n",ans);
  }
  return 0;
}

你可能感兴趣的:(BZOJ 4052: [Cerc2013]Magical GCD)