POI2012 ODL-Distance

时间:2018-11-07 19:17:24   收藏:0   阅读:126

链接P3532 [POI2012]ODL-Distance

#include<bits/stdc++.h>
#define R register int
#define ll long long 
using namespace std;
const int N=1000001;
const int inf=2e9;
int n,Mx,w[N],ans[N];
int tot,c[N],f[N],g[N],cnt[N],Mark[N],prm[N>>2];
int gi(){
    R x=0,k=1;char c=getchar();
    while((c<‘0‘||c>‘9‘)&&c!=‘-‘)c=getchar();
    if(c==‘-‘)k=-1,c=getchar();
    while(c>=‘0‘&&c<=‘9‘)x=(x<<3)+(x<<1)+c-‘0‘,c=getchar();
    return x*k;
}
void init(){
    for(R i=2;i<=Mx;++i){
        if(!Mark[i])prm[++tot]=i,c[i]=1;
        for(R j=1;j<=tot&&prm[j]*i<=Mx;++j){
            Mark[i*prm[j]]=1,c[i*prm[j]]=c[i]+1;
            if(i%prm[j]==0)break;
        }
    }
}
int main(){
    freopen("9.in","r",stdin);
    freopen("s.out","w",stdout);
    n=gi();
    for(R i=1;i<=n;++i)w[i]=gi(),Mx=max(Mx,w[i]);
    init(),c[0]=2e9;
    for(R i=1;i<=n;++i){
        for(R j=1;j*j<=w[i];++j){
            if(w[i]%j)continue;
            R k=w[i]/j;
            if(c[w[i]]<c[w[f[j]]])g[j]=f[j],f[j]=i;
            else if(c[w[i]]<c[w[g[j]]])g[j]=i;
            if(j==k)continue;
            if(c[w[i]]<c[w[f[k]]])g[k]=f[k],f[k]=i;
            else if(c[w[i]]<c[w[g[k]]])g[k]=i;
        }
    }
    for(R i=1;i<=n;++i){
        R ans=0,Mn=2e9;
        for(R j=1;j*j<=w[i];++j){
            if(w[i]%j)continue;
            R k=w[i]/j,x=0;
            if(f[j]==i)x=g[j];
            else x=f[j];
            if(Mn>c[w[i]]+c[w[x]]-2*c[j]||(Mn==c[w[i]]+c[w[x]]-2*c[j]&&ans>x))
                Mn=c[w[i]]+c[w[x]]-2*c[j],ans=x;
            if(j==k)continue;
            if(f[k]==i)x=g[k];
            else x=f[k];
            if(Mn>c[w[i]]+c[w[x]]-2*c[k]||(Mn==c[w[i]]+c[w[x]]-2*c[k]&&ans>x))
                Mn=c[w[i]]+c[w[x]]-2*c[k],ans=x;
        }
        printf("%d\n",ans);
    }
    return 0;
}

原文:https://www.cnblogs.com/Tyher/p/9924682.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!