bzoj 4052: [Cerc2013]Magical GCD

Description

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

Input

Output

Sample Input

1
5
30 60 20 20 20

Sample Output

80

因为不同gcd数量很少。所以直接暴力即可
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
struct save
{
     long long num;
     int x;
     bool operator <(save y) const
     {
          return num<y.num||(num==y.num&&x<y.x);
     }
};
long long a[100001];
save f[2][100001];
inline long long gcd(long long x,long long y)
{
     long long m=x%y;
     while(m!=0)
     {
          x=y;
          y=m;
          m=x%y;
     }
     return y;
}
int main()
{
	 int T;
	 scanf("%d",&T);
	 while(T>0)
	 {
	 	  T--;
	      int n;
	      scanf("%d",&n);
	      int i,j,k;
	      for(i=1;i<=n;i++)
	           scanf("%lld",&a[i]);
	      long long ans=0;
	      int p=0,q=1;
	      int s1=0,s2=0;
	      save d;
	      for(i=1;i<=n;i++)
	      {
	           for(j=1;j<=s1;j++)
	                f[p][j].num=gcd(a[i],f[p][j].num);
               d.num=a[i];
               d.x=i;
               s1++;
               f[p][s1]=d;
               sort(f[p]+1,f[p]+s1+1);
               s2=0;
               for(j=1;j<=s1;j++)
               {
                    if(f[p][j].num!=f[p][j-1].num)
                    {
                         s2++;
                         f[q][s2]=f[p][j];
                    }
               }
               for(j=1;j<=s2;j++)
                    ans=max(ans,f[q][j].num*(long long)(i-f[q][j].x+1));
               p^=1;
               q^=1;
               s1=s2;
	      }
	      printf("%lld\n",ans);
	 }
     return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值