可以对每个Ai的所有约数xi求它到Ai的距离,然后被枚举的所有数维护他到Ai的最小值和次小值,然后对每个Ai求Aj的时候就可以枚举它的约数,如果最小值i和j重复就询问次小值
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define lowbit(x) x&(-x)using namespace std;const int maxn = 110000;const int maxm = 1100000;int a[maxn],n;int p[maxm],PRi,minp[maxm],s[maxm];bool v[maxm];void pre(){ memset(v,false,sizeof v); s[1]=0; pri=0; for(int i=2;i<maxm;i++) { if(!v[i]) { p[++pri]=i; minp[i]=i; s[i]=1; } for(int j=1;j<=pri;j++) { int k=i*p[j]; if(k>=maxm) break; v[k]=true; minp[k]=p[j]; s[k]=s[i]+1; if(i%p[j]==0) break; } }}int d[maxm][2],di[maxm][2];void g_d(){ memset(d,63,sizeof d); for(int i=1;i<=n;i++) { int x=a[i]; int k=sqrt(x); for(int j=1;j<=k;j++) { int l=j; if(x%j==0) { if(d[j][0]>s[x/j]) { d[j][1]=d[j][0]; di[j][1]=di[j][0]; d[j][0]=s[x/j]; di[j][0]=i; } else if(d[j][1]>s[x/j]) { d[j][1]=s[x/j]; di[j][1]=i; } if(j*j==x) break; j=x/j; if(d[j][0]>s[x/j]) { d[j][1]=d[j][0]; di[j][1]=di[j][0]; d[j][0]=s[x/j]; di[j][0]=i; } else if(d[j][1]>s[x/j]) { d[j][1]=s[x/j]; di[j][1]=i; } } j=l; } }}int main(){ pre(); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); g_d(); for(int i=1;i<=n;i++) { int x=a[i]; int k=sqrt(x); int ansx=INT_MAX,ansy=n+1; for(int j=1;j<=k;j++) if(x%j==0) { int jl=j; int xk=x/j; int l=di[j][0]==i; int nws=s[xk]+d[j][l]; if(ansx>nws||(ansx==nws&&ansy>di[j][l])) { ansx=nws; ansy=di[j][l]; } if(j*j==x) break; j=x/j; xk=x/j; l=di[j][0]==i; nws=s[xk]+d[j][l]; if(ansx>nws||(ansx==nws&&ansy>di[j][l])) { ansx=nws; ansy=di[j][l]; } j=jl; } printf("%d/n",ansy); } return 0;}新闻热点
疑难解答