因为只有奇数个质因子和偶数个质因子间可以匹配,所以如果在可以配对的点间连边,得到的图是二分图。
然后跑费用流直到价值总和小于
0
<script type="math/tex" id="MathJax-Element-19">0</script> 就好了。注意判断临界情况。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=210;
const int M=21000;
const int MX=64000;
const int INF=1e9;
int a[N],b[N],s[N];
int k,n,m;
int h[N],nx[M],t[M],c[M],f[M],num=1;
ll w[M],d[M];
int mn[N];
int l,r,q[M],p[N];
int Ans;
ll Sum;
bool g[N],v[N];
int pri[100000],cnt;
bool pd[MX];
inline bool Get(int x){
bool b=0;
for(int i=2;i*i<=x;i++)
while(!(x%i))x/=i,b^=1;
if(x>1)b^=1;
return b;
}
inline bool cc(int x){
if(x==1)return 0;
for(int i=1;i<=cnt;i++){
if(pri[i]*pri[i]>x)break;
if(!(x%pri[i]))return 0;
}
return 1;
}
inline bool Check(int x,int y){
if(!x||!y)return 0;
if(x>y)swap(x,y);
return (!(y%x)&&cc(y/x));
}
inline void Add(int x,int y,int z,ll k){
t[++num]=y;f[num]=x;c[num]=z;w[num]=k;nx[num]=h[x];h[x]=num;
t[++num]=x;f[num]=y;c[num]=0;w[num]=-k;nx[num]=h[y];h[y]=num;
}
inline bool Spfa(){
memset(v,0,sizeof(v));memset(p,0,sizeof(p));
v[0]=1;
for(int i=1;i<=n+1;i++)d[i]=-1e18;
l=0;q[r=1]=0;mn[0]=INF;
while(++l<=r){
int x=q[l];
for(int i=h[x];i;i=nx[i])
if(c[i]&&d[t[i]]<d[x]+w[i]){
d[t[i]]=d[x]+w[i];p[t[i]]=i;mn[t[i]]=min(mn[x],c[i]);
if(!v[t[i]]){
q[++r]=t[i];
v[t[i]]=1;
}
}
v[x]=0;
}
if(!p[n+1])return 0;
int fl=mn[n+1];
if(Sum+d[n+1]*fl<0){
Ans-=Sum/d[n+1];
return 0;
}
Sum+=d[n+1]*fl;Ans+=fl;
for(int i=n+1;i;i=f[p[i]])c[p[i]]-=fl,c[p[i]^1]+=fl;
return 1;
}
inline void Init(){
for(int i=2;i<MX;i++){
if(!pd[i])pri[++cnt]=i;
int t;
for(int j=1;j<=cnt&&(t=i*pri[j])<MX;j++){
pd[t]=1;
if(!(i%pri[j]))break;
}
}
}
int main(){
scanf("%d",&n);
Init();
for(int i=1;i<=n;i++)scanf("%d",&a[i]),g[i]=Get(a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
for(int i=1;i<=n;i++)scanf("%d",&s[i]);
for(int i=1;i<=n;i++)
if(g[i])
for(int j=1;j<=n;j++)
if(!g[j]&&Check(a[i],a[j]))Add(i,j,INF,1ll*s[i]*s[j]);
for(int i=1;i<=n;i++)
if(g[i])Add(0,i,b[i],0);else Add(i,n+1,b[i],0);
while(Spfa());
cout<<Ans<<endl;
return 0;
}