直接用埃氏筛也可以做,但是这题写起来有点恶臭。。
更加简单的写法是直接枚举gcd=k,然后里面再枚举一次i*k,即找到k两个最小的倍数,看起来复杂度很高,但其实也是埃氏筛的复杂度
因为每次枚举gcd,相当于筛法中的枚举筛数,不同的是这题对于每个i在筛的过程中,不会筛到低,而是会中途退出循环,那么当其倍数i*k继续去筛的时候,仅仅是原来应该筛的数筛掉而已
int value[10000007][2]; int main() { int n; scanf("%d",&n); memset(value,0,sizeof(value)); for(int i = 1;i<=n;i++){ int x; scanf("%d",&x); if(value[x][0]){ value[x][1]=i; } else{ value[x][0]=i; } } LL ans=1e18,ansx,ansy; for(int i = 1;i<=1e7;i++){ vector<pll> v; for(int k=1;k*i<=1e7;k++){ if(value[k*i][0]){ v.pb(mp(k,value[k*i][0])); } if(value[k*i][1]){ v.pb(mp(k,value[k*i][1])); } if(v.size()>=2) break; } if(v.size()<2) continue; LL lcm=i*v[0].x*v[1].x; if(lcm<ans){ ans=lcm; ansx=v[0].y; ansy=v[1].y; } } if(ansx>ansy) swap(ansx,ansy); printf("%lld %lld\n",ansx,ansy); }