【数论】【暴力】bzoj4052 [Cerc2013]Magical GCD

本文介绍了一种通过维护不同最大公约数(GCD)及其初始位置的表来优化算法的方法。该算法适用于向集合中添加元素时,GCD要么不变要么变为原GCD的约数的情况。通过这种方式可以有效地更新答案,确保表的长度始终保持较短。
摘要由CSDN通过智能技术生成

考虑向一个集合里添加一个数,它们的gcd要么不变,要么变成原gcd的一个约数。因此不同的gcd只有log个。

所以对于每个位置,维护一个表,存储从这个位置向前所有的不同的gcd及其初始位置,然后暴力更新答案,反正这个表不会很长。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 100001
typedef long long ll;
typedef pair<ll,int> Point;
Point table[101],t[101];
int T,n,en,e2;
ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
int main()
{
	ll x;
	scanf("%d",&T);
	for(;T;--T)
	  {
	  	ll ans=0;
	  	en=0;
	  	scanf("%d",&n);
	  	for(int i=1;i<=n;++i)
	  	  {
	  	  	scanf("%lld",&x);
	  	  	for(int j=1;j<=en;++j)
	  	  	  table[j].first=gcd(table[j].first,x);
	  	  	table[++en]=make_pair(x,i);
	  	  	sort(table+1,table+1+en);
	  	  	e2=0;
	  	  	for(int j=1;j<=en;++j)
	  	  	  if(table[j].first!=table[j-1].first)
	  	  	    t[++e2]=table[j];
	  	  	en=e2;
	  	  	memcpy(table+1,t+1,sizeof(Point)*e2);
	  	  	for(int j=1;j<=en;++j)
	  	  	  ans=max(ans,table[j].first*(ll)(i-table[j].second+1));
	  	  }
	  	printf("%lld\n",ans);
	  }
	return 0;
}

转载于:https://www.cnblogs.com/autsky-jadek/p/4496321.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值