您的位置:首页 > 其它

【BZOJ 4052】[Cerc2013]Magical GCD 暴力+gcd

2017-03-27 11:54 337 查看
有一个套路就是每一次加入一个数字区间的gcd肯定是不上升的,而每一次下降也会是至少下降为1/2,所以本质不同的gcd的个数并不会有太多,既然这样就可以枚举右端点然后暴力维护左端点有相同的gcd就删除l大的那一个然后就好。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 100021
#define LL long long
using namespace std;
LL n,a[maxn],ans,cnt,T;
LL gcd(LL a,LL b){return !b ? a : gcd(b,a%b);}
struct G{
LL l,x;
bool operator<(const G& b)const {
return x==b.x ? l<b.l : x<b.x;
}
}g[maxn];
void solve(LL x,LL id){
for(LL i=1;i<=cnt;i++){
g[i].x=gcd(g[i].x,x);
ans=max(ans,(id-g[i].l+1)*g[i].x);
}
}
void del(){
sort(g+1,g+1+cnt);
LL v=0;
for(LL i=1;i<=cnt;i++){
if(i==1||g[i].x!=g[i-1].x)g[++v]=g[i];
}cnt=v;
}
int main(){
scanf("%lld",&T);
while(T--){
ans=0,cnt=0;
scanf("%lld",&n);
for(LL i=1;i<=n;i++)scanf("%lld",a+i);
for(LL i=1;i<=n;i++){
g[++cnt]=(G){i,a[i]};
solve(a[i],i);
del();
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: