Task
对于两个正整数a、b,这样定义函数d(a,b):每次操作可以选择一个质数p,将a变成a*p或a/p,
如果选择变成a/p就要保证p是a的约数,d(a,b)表示将a变成b所需的最少操作次数。例如d(69,42)=3。
现在给出n个正整数A1,A2,…,An,对于每个i (1<=i<=n),求最小的j(1<=j<=n)使得i≠j且d(Ai,Aj)最小。
2<=n<=100,000, Ai<=1,000,000.
Solution
设cnt[i]为i的质因子个数,d(a,b)=cnt[a]-cnt[b]-2*cnt[gcd(a,b)],对于每个i,考虑枚举A[i]与A[j]的gcd,假设为k.剩下不确定的答案就是A[j]了,为了让cnt[A[j]]尽可能小,可以预处理出dp[k],表示k的倍数中cnt最小的下标t.为了防止t=i,对于每个k,需要求出前两小的下标.
Ai≤10^6,因子个数最多为240个,可以直接暴力枚举每个值的所有因子进行求解.
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define ll long long
#include<queue>
#include<set>
using namespace std;
inline void rd(int &res){
res=0;char c;
while(c=getchar(),c<48);
do res=(res<<1)+(res<<3)+(c^48);
while(c=getchar(),c>=48);
}
inline void print(ll x){
if(!x)return ;
print(x/10);
putchar((x%10)^48);
}
inline void sc(ll x){
if(x<0){x=-x;putchar('-');}
print(x);
if(!x)putchar('0');
putchar('\n');
}
inline void Max(int &x,int y){if(x<y)x=y;}
inline void Min(int &x,int y){if(x>y)x=y;}
const int M=1e6+5;
const int N=1e5+5;
int mark[M],son[M][10],cnt[M][10],A[N],mx=0;
vector<int>rec[M];
struct node{
int v,id;
node(){id=-1,v=-1;}
bool operator<(const node &tmp)const{
if(tmp.v!=v)return v<tmp.v;
return id<tmp.id;
}
}h[M][2],ans[N];
void Init(){
for(int i=2;i*i<=mx;i++){
if(!mark[i]){
for(int j=i;j<=mx;j+=i){
son[j][++son[j][0]]=i;
mark[j]=1;
}
}
}
}
void Up(int x,node y){//y是x的倍数
// if(h[x][0].id==-1)h[x][0]=y;
if(h[x][0].id==-1||y<h[x][0]){
h[x][1]=h[x][0];
h[x][0]=y;
}
else if(h[x][1].id==-1||y<h[x][1]){
h[x][1]=y;
}
}
void dfs(int id,int x,int p,int num){
if(p==son[x][0]+1){
node y;
y=h[num][0];
if(h[num][0].id==id)y=h[num][1];
if(~y.v){
y.v+=cnt[x][0]-2*cnt[num][0];
if(ans[id].id==-1||y<ans[id])ans[id]=y;
}
return;
}
for(int i=0;i<=cnt[x][p];i++){
dfs(id,x,p+1,num);
num*=son[x][p];
}
}
int main(){
int n,i,j,cas,a,b,k;
rd(n);
for(i=1;i<=n;i++){
rd(A[i]);Max(mx,A[i]);
rec[A[i]].push_back(i);
}
Init();
for(i=2;i<=mx;i++){
int x=i;
for(j=1;j<=son[i][0];j++){
a=0;
while(x%son[i][j]==0){a++;x/=son[i][j];}
cnt[i][j]=a;
cnt[i][0]+=a;
}
if(x!=1){
son[i][++son[i][0]]=x;
cnt[i][son[i][0]]=1;
cnt[i][0]++;
}
}
for(i=1;i<=mx;i++){
for(j=i;j<=mx;j+=i){
if(!rec[j].size())continue;
node y;
y.v=cnt[j][0];
for(k=0;k<rec[j].size();k++){
y.id=rec[j][k];
Up(i,y);
}
}
}
for(i=1;i<=n;i++)dfs(i,A[i],1,1);
for(i=1;i<=n;i++)sc(ans[i].id);
return 0;
}