poi2012 distance
stupid_lulu
posted @ 2013年3月24日 15:16
in poi
, 1745 阅读
暴力水过。。就是d(a,b)=c[a]+c[b]-c[gcd(a,b)];c[i]表示i的质因子数。然后对每个a[i]暴力枚举gcd(),求一个b使c[a]+c[b]-2*c[gcd()]最小。。这个可以预处理后O(1)解决。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxi=1000000000;
int n,m=0,tot=0;
bool ss[1000051];
int prime[1000051];
int f[1000051],g[1000051];
int a[1000051],c[1000051];
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
m=max(m,a[i]);
}
memset(ss,true,sizeof(ss));
for (int i=2;i<=m;i++){
if (ss[i]){
prime[++tot]=i;
c[i]=1;
}
for (int j=1;j<=tot&&prime[j]*i<=m;j++){
int k=i*prime[j];
ss[k]=false;
c[k]=c[i]+1;
if (i%prime[j]==0) break;
}
}
//for (int i=1;i<=tot;i++) printf("prime[%d]=%d\n",i,prime[i]);
//for (int i=1;i<=m;i++) printf("c[%d]=%d\n",i,c[i]);
c[0]=maxi;
for (int i=1;i<=n;i++){
for (int j=1;j*j<=a[i];j++){
if (a[i]%j!=0) continue;
int k=a[i]/j;
//printf("i=%d j=%d k=%d\n",i,j,k);
if (c[a[i]]<c[a[f[j]]]){g[j]=f[j]; f[j]=i;}
else if (c[a[i]]<c[a[g[j]]]) g[j]=i;
//printf("g=%d f=%d\n",g[j],f[j]);
if (j==k) continue;
if (c[a[i]]<c[a[f[k]]]){g[k]=f[k]; f[k]=i;}
else if (c[a[i]]<c[a[g[k]]]) g[k]=i;
}
//if (i%10000==0) printf("i=%d\n",i);
}
//for (int i=1;i<=m;i++) printf("i=%d f=%d g=%d\n",i,f[i],g[i]);
for (int i=1;i<=n;i++){
int h=maxi,d=0;
for (int j=1;j*j<=a[i];j++){
if (a[i]%j!=0) continue;
int k=a[i]/j,x;
if (f[j]==i) x=g[j];
else x=f[j];
//printf("i=%d x=%d j=%d k=%d h=%d\n",i,x,j,k,h[i]);
if (h>c[a[i]]+c[a[x]]-2*c[j]||(h==c[a[i]]+c[a[x]]-2*c[j]&&x<d)){
h=c[a[i]]+c[a[x]]-2*c[j];
d=x;
}
if (j==k) continue;
if (f[k]==i) x=g[k];
else x=f[k];
if (h>c[a[i]]+c[a[x]]-2*c[k]||(h==c[a[i]]+c[a[x]]-2*c[k]&&x<d)){
h=c[a[i]]+c[a[x]]-2*c[k];
d=x;
}
}
//if (i%10000==0) printf("%d\n",i);
printf("%d\n",d);
}
}
2024年2月21日 23:57
i am for the first time here. I found this board and I in finding It truly helpful & it helped me out a lot. I hope to present something back and help others such as you helped me.