BZOJ 2790「POI2012」Distance

#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rel(i,x,y) for(ll i=(x);i<(y);i++)
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define red(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=1e6+5;
const ll Inf=1e18;

ll n,mx,a[N],p[N],val[N],vis[N],pri[N],ans[N];

vector<ll>v[N];

inline ll read() {
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

inline void chkmx(ll &a,ll b) {
	a=a>b?a:b;
}

int main() {
	memset(val,127,sizeof(val));
	
	n=read();
	
	rep(i,1,n) a[i]=read(),chkmx(mx,a[i]);
	
	rep(i,2,mx) {
		if(!vis[i]) pri[++pri[0]]=i,p[i]=1;
		
		rep(j,1,pri[0]) {
			if(i*pri[j]>mx) break;
			vis[i*pri[j]]=1;
			p[i*pri[j]]=p[i]+1;
			if(i%pri[j]==0) break;
		}
	}
	
	rep(i,1,n) {
		ll s=sqrt(a[i]);
		rep(j,1,s) {
			if(a[i]%j==0) {
				v[j].push_back(i);
				if(j*j!=a[i]) v[a[i]/j].push_back(i);
			}
		}
	}
	
	rep(i,1,mx) {
		ll m=v[i].size();
        if(m<=1) continue;
        ll ma,sa,mv=Inf,sv=Inf;
        
        rel(j,0,m) {
        	ll t=v[i][j],t1=p[a[t]/i];
            if(t1<mv||(t1==mv&&ma>t)) sa=ma,sv=mv,ma=t,mv=t1;
            else if(t1<sv||(t1==sv&&sa>t)) sa=t,sv=t1;
		}
        rel(j,0,m) {
        	ll t=v[i][j],t1=p[a[t]/i];
            if(t==ma) {
            	if(val[t]>t1+sv||(val[t]==t1+sv&&ans[t]>sa)) val[t]=t1+sv,ans[t]=sa;
			} else if(val[t]>t1+mv||(val[t]==t1+mv&&ans[t]>ma)) val[t]=t1+mv,ans[t]=ma;
		}
	}
	
	rep(i,1,n) printf("%lld ",ans[i]);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/83155542