【NOIP2014模拟8.17】Magical GCD

Description

对于一个由正整数组成的序列, Magical GCD 是指一个区间的长度乘以该区间内所有数字的最大公约数。给你一个序列,求出这个序列最大的 Magical GCD。

Input

单个测试点包含多组数据。

输入的第一行是一个整数T表示数据组数。

每组数据的第一行是一个整数N,描述序列长度。

接下来N个数字,描述这个序列元素A[i]。

Output

对于每组测试数据输出一行,包含一个整数,表示序列最大的 Magical GCD。

题解

暴力出正解。
注:int64!!

代码

var
  t,n,m:longint;
  ans:int64;
  a,b:array [0..100001] of int64;
  l:array[0..100001] of longint;
function gcd(o,p:int64):int64;
begin
  if p=0 then exit(o);
  exit(gcd(p,o mod p));
end;

function max(o,p:int64):int64;
begin
  if o>p then exit(o);
  exit(p);
end;

procedure init;
var
  i:longint;
begin
  readln(n);
  ans:=0; m:=1; l[1]:=1;
  for i:=1 to n do
    begin
      read(a[i]);
      ans:=max(ans,a[i]);
    end;
  for i:=1 to n-1 do
    b[i]:=gcd(a[i],a[i+1]);
  for i:=1 to n-2 do
    if (b[i] mod b[i+1])<>0 then
      begin
        inc(m); l[m]:=i+1;
      end;
  l[0]:=-1; l[m+1]:=maxlongint;
end;

procedure main;
var
  i,j,len:longint;
  gcdt:int64;
begin
  len:=0;
  for i:=1 to n-1 do
    begin
      while l[len]<=i do inc(len);
      dec(len); gcdt:=b[i];
      for j:=len downto 1 do
        begin
          ans:=max(ans,(i-l[j]+2)*gcdt);
          gcdt:=gcd(gcdt,b[l[j]-1]);
          if gcdt=1 then
            begin
              ans:=max(ans,i+1);
              break;
            end;
        end;
    end;
end;

begin
  readln(t);
  while t>0 do
    begin
      init;
      main;
      writeln(ans);
      dec(t);
    end;
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值