bzoj 4488: [Jsoi2015]最大公约数

Description

给定一个长度为 N 的正整数序列Ai对于其任意一个连续的子序列
{Al,Al+1...Ar},我们定义其权值W(L,R )为其长度与序列中所有元素的最大公约数的乘积,即W(L,R) = (R-L+1) ∗ gcd (Al..Ar)。 
JYY 希望找出权值最大的子序列。

Input

输入一行包含一个正整数 N。
接下来一行,包含 N个正整数,表示序列Ai
1 < =  Ai < =  10^12, 1 < =  N < =  100,000

Output

输出文件包含一行一个正整数,表示权值最大的子序列的权值。

Sample Input

5
30 60 20 20 20

Sample Output

80
//最佳子序列为最后 4 个元素组成的子序列。

http://blog.csdn.net/lqybzx/article/details/45695547
↑同4052
考试的前几天才做过这题。。仿佛那次JSOI是5题还是6题原题的来着
#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);
	 T=1;
	 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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值