the
There are n kinds of numbers, the first number is AI, there are bi, the weight is CI.
If two digital AI, AJ satisfied, AI is a multiple of AJ, and Ai/aj is a prime number,
So these two numbers can be paired and get the value of CIXCJ.
A number can only participate in a single pairing, and may not participate in the pairing.
If the sum of the values obtained is not less than 0, ask for the maximum number of pairs.
N≤200,ai≤10^9,bi≤10^5,∣ci∣≤10^5 Analysis
Set F (x) to denote the sum of the exponent of the standard factorization of x, then I and J matches must satisfy A[i]%a[j]==0 and F (A[i]) ==f (a[j)) +1
Then we can dye it in black and white in accordance with the parity of F (a[i]).
Two points after the edge of the answer then determine the maximum cost maximum flow is not less than 0 can be. Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include < algorithm> #include <cmath> #include <queue> #define N 205 #define LL Long long #define INF 0x7fffffff using
namespace Std;
int n,a[n],b[n],c[n],cnt,last[n],s,t,s,pre[n],vis[n],col[n],maxf,sum,prime[n*n],not_prime[n*n],low[n*n];
LL Dis[n],ans; struct Edge{int from,to,next,c; LL W;}
E[N*N*5];
Queue <int> q;
void Get_prime (int n) {for (int i=2;i<=n;i++) {if (!not_prime[i]) prime[++sum]=i,low[i]=sum; for (int j=1;j<=sum&&i*prime[j]<=n;j++) {Not_prime[i*prime[j]]=1;low[i*prime[j]]=prime
[j];
if (i%prime[j]==0) break; }} void Addedge (int u,int v,int c,ll w) {E[++cnt].from=u;e[cnt].to=v;e[cnt].c=c;e[cnt].w=w;e[cnt].next=last[u
];last[u]=cnt;
e[++cnt].from=v;e[cnt].to=u;e[cnt].c=0;e[cnt].w=-w;e[cnt].next=last[v];last[v]=cnt; BOOL Spfa () {for (int i=0;i<=s;i++) DIS[I]=-1E15;
Q.push (S); vis[s]=1;dis[s]=0;
while (!q.empty ()) {int U=q.front ();
Q.pop ();
for (int i=last[u];i;i=e[i].next) if (e[i].c&&dis[u]+e[i].w>dis[e[i].to]) {
DIS[E[I].TO]=DIS[U]+E[I].W;
Pre[e[i].to]=i;
if (!vis[e[i].to]) {vis[e[i].to]=1;
Q.push (e[i].to);
}} vis[u]=0;
} if (DIS[T]==-1E15) return 0;
else return 1;
} void Mcf () {int mn=inf,x=t;
while (Pre[x]) {mn=min (MN,E[PRE[X]].C);
X=e[pre[x]].from;
} ans+= (LL) mn*dis[t];
MAXF+=MN;
x=t;
while (Pre[x]) {e[pre[x]].c-=mn;
E[PRE[X]^1].C+=MN;
X=e[pre[x]].from;
} bool Check (int mid) {e[cnt^1].c=mid;e[cnt].c=0;
for (int i=2;i<=cnt;i+=2) e[i].c+=e[i^1].c,e[i^1].c=0;
ans=0;maxf=0;
while (SPFA ()) MCF (); if (aNs>=0&&maxf==mid) return 1;
else return 0;
int main () {get_prime (40000);
scanf ("%d", &n);
int tot=0;
for (int i=1;i<=n;i++) scanf ("%d", &a[i]);
for (int i=1;i<=n;i++) scanf ("%d", &b[i]), tot+=b[i];
for (int i=1;i<=n;i++) scanf ("%d", &c[i]);
for (int i=1;i<=n;i++) {int x=a[i];
for (int j=1;j<=sum;j++) if (x%prime[j]==0) {while (x%prime[j]==0)
{COL[I]++;X/=PRIME[J];
}} cnt=1;
for (int i=1;i<=n;i++) if (col[i]%2==0) for (int j=1;j<=n;j++) if (col[j]%2==1)
{int x=i,y=j;
if (A[x]>a[y]) swap (x,y);
if (A[y]%a[x]==0&&col[x]+1==col[y]) Addedge (I,j,inf, (LL) c[i]*c[j]); } s=0;t=n+1;
s=n+2; for (int i=1;i<=n;i++) if (col[i]%2==0) Addedge (s,i,b[i],0);
else Addedge (i,t,b[i],0);
Addedge (s,s,0,0);
int L=1,r=tot;
while (l<=r) {int mid= (L+R)/2;
if (check (mid)) l=mid+1;
else r=mid-1;
printf ("%d", l-1);
return 0; }