cf1154G 埃氏筛应用

直接用埃氏筛也可以做,但是这题写起来有点恶臭。。

更加简单的写法是直接枚举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);
}
原文地址:https://www.cnblogs.com/zsben991126/p/10725803.html