重点是如何找到可以配对的\(a[i]\)和\(a[j]\)。

把\(a[i]\)分解质因数。设\(a[i]\)分解出的质因数的数量为\(cnt[i]\)。

设\(a[i]\geq a[j]\)

那么\(a[i]\)可以和\(a[j]\)配对需要满足\(a[i]\)%\(a[j]==0\)&&\(cnt[i]==cnt[j]+1\)

证明显然。

然后我们按\(cnt[i]\)的奇偶分成两部分,然后如果\(a[i]\)和\(a[j]\)可以配对(假设a[i]在左边)从\(i\)向\(j\)连一条费用为\(c[i]*c[j\)],流量为\(INF\)的边。

然后\(S\)向左部点连费用为\(0\),流量为\(b[i]\)的边。

然后每一个右部点向\(T\)连费用为\(0\),流量为\(b[i]\)的边。

跑费用流。

因为费用流优先走最长路。

所以我们可以贪心。

当总费用刚好为负时结束就好了。

具体来说这次增广前的总费用为\(tot\),总流量为\(w\)。

然后这次最长路长度为\(x\),可以增广的流量为\(tmp\)。

且\(tot+x*tmp<0\),答案就是\(w+\lfloor \frac{tot}{x} \rfloor\)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define int long long
const int N=233;
const int INF=1e14;
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int book[101000],prime[100100],tot;
void pre_work(int n){
for(int i=2;i<=n;i++){
if(book[i]==0)prime[++tot]=i;
for(int j=1;j<=tot&&prime[j]*i<=n;j++){
book[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
int work(int x){
int tmp=0;
for(int i=1;prime[i]*prime[i]<=x;i++)
if(x%prime[i]==0){
while(x%prime[i]==0)x/=prime[i],tmp++;
}
if(x>1)tmp++;
return tmp;
}
struct edge{
int to,nxt,flow,cost;
}e[N*N*2];
int cnt=1,head[N];
void add_edge(int u,int v,int flow,int cost){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
e[cnt].flow=flow;
e[cnt].cost=cost;
head[u]=cnt;
cnt++;
e[cnt].nxt=head[v];
e[cnt].to=u;
e[cnt].flow=0;
e[cnt].cost=-cost;
head[v]=cnt;
}
int dis[N],vis[N],road[N],S,T,tmp,ans;
bool spfa(){
for(int i=S;i<=T;i++)dis[i]=INF;
queue<int> q;
q.push(S);
dis[S]=0;
vis[S]=1;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(e[i].flow&&dis[v]>dis[u]+e[i].cost){
dis[v]=dis[u]+e[i].cost;
road[v]=i;
if(vis[v]==0){
vis[v]=1;
q.push(v);
}
}
}
}
if(dis[T]==INF)return false;
int mn=INF;
for(int i=T;i!=S;i=e[road[i]^1].to)
mn=min(e[road[i]].flow,mn);
if(tmp+mn*dis[T]>0){
ans+=-tmp/dis[T];
return false;
}
tmp+=mn*dis[T];
ans+=mn;
for(int i=T;i!=S;i=e[road[i]^1].to){
e[road[i]].flow-=mn;
e[road[i]^1].flow+=mn;
}
return true;
}
int n,a[N],b[N],c[N],w[N];
signed main(){
pre_work(100000);
n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)b[i]=read();
for(int i=1;i<=n;i++)c[i]=read();
for(int i=1;i<=n;i++)w[i]=work(a[i]);
S=0;T=n+1;
for(int i=1;i<=n;i++)
if(w[i]%2==1)add_edge(S,i,b[i],0);
else add_edge(i,T,b[i],0);
for(int i=1;i<=n;i++){
if(w[i]%2==0)continue;
for(int j=1;j<=n;j++){
if(w[j]%2==1)continue;
if((a[j]%a[i]==0&&w[j]==w[i]+1)||(a[i]%a[j]==0&&w[i]==w[j]+1))
add_edge(i,j,INF,-c[i]*c[j]);
}
}
while(spfa());
printf("%lld",ans);
return 0;
}

[SDOI2016]数字配对(费用流+贪心+trick)的更多相关文章

  1. 【BZOJ4514】[Sdoi2016]数字配对 费用流

    [BZOJ4514][Sdoi2016]数字配对 Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ...

  2. BZOJ 4514: [Sdoi2016]数字配对 [费用流 数论]

    4514: [Sdoi2016]数字配对 题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数 ...

  3. BZOJ.4514.[SDOI2016]数字配对(费用流SPFA 二分图)

    BZOJ 洛谷 \(Solution\) 很显然的建二分图后跑最大费用流,但有个问题是一个数是只能用一次的,这样二分图两部分都有这个数. 那么就用两倍的.如果\(i\)可以向\(j'\)连边,\(j\ ...

  4. bzoj4514: [Sdoi2016]数字配对--费用流

    看了一眼题目&数据范围,觉得应该是带下界的费用流 原来想拆点变成二分图,能配对的连边,跑二分图,可行性未知 后来看到另外一种解法.. 符合匹配要求的数要满足:质因子的个数相差为1,且两者可整除 ...

  5. 4514: [Sdoi2016]数字配对 费用流

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4514 思路 EK直接贪心做 <0的时候加上剩余返回 二分图a->b的时候 把b- ...

  6. 【BZOJ 4514】[Sdoi2016]数字配对 费用流

    利用spfa流的性质,我直接拆两半,正解分奇偶(妙),而且判断是否整除且质数我用的是暴力根号,整洁判断质数个数差一(其他非spfa流怎么做?) #include <cstdio> #inc ...

  7. 【BZOJ4514】【SDOI2016】数字配对 [费用流]

    数字配对 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 有 n 种数字,第 i 种数字是 ...

  8. [bzoj4514]数字配对[费用流]

    今年SDOI的题,看到他们在做,看到过了一百多个人,然后就被虐惨啦... 果然考试的时候还是打不了高端算法,调了...几天 默默地yy了一个费用流构图: 源连所有点,配对的点连啊,所有点连汇... 后 ...

  9. [SDOI2016][bzoj4514] 数字配对 [费用流]

    题面 传送门 思路 一个数字能且只能匹配一次 这引导我们思考:一次代表什么?代表用到一定上限(b数组)就不能再用,同时每用一次会产生价值(c数组) 上限?价值?网络流! 把一次匹配设为一点流量,那产生 ...

随机推荐

  1. Ningx初学

    原文地址 1. 到官网下载Ningx 2. 启动 2.1双击nginx.exe图标,可见黑窗口一闪而过,启动完毕. 2.2 命令行到nginx目录,输入nginx启动.(注,此方式命令行窗口无任何提示 ...

  2. mysql 服务器监控系列-黄杉 mysqldba

    http://blog.csdn.net/mchdba/article/category/2220809

  3. WebApplicationInitializer究 Spring 3.1之无web.xml式 基于代码配置的servlet3.0应用

    本文转自http://hitmit1314.iteye.com/blog/1315816 大家应该都已经知道Spring 3.1对无web.xml式基于代码配置的servlet3.0应用.通过spri ...

  4. Welcome to the Real World

     Welcome to the Real World Gregor Hohpe EnginEERS liKE pRECiSion, especially software engineers who ...

  5. HDU 4531

    很容易判断是BFS,可是,呵呵呵呵呵呵......... HASH判重吧,判连通可以用并查集. 以下代码是转别人的,我码了一下午,发觉越码越丑,呵呵了. http://www.cnblogs.com/ ...

  6. Codeforces 474 C. Captain Marmot

    4*4*4*4暴力+点的旋转+推断正方型 C. Captain Marmot time limit per test 1 second memory limit per test 256 megaby ...

  7. HDU 2717

    Catch That Cow Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  8. php简单的连接数据库

    <?php $conn=@mysql_connect("localhost","root","") or die ("no& ...

  9. AUTOCAD2013 以上利用ACCORECONSOLE+ SCR后台批量清理图纸

    无意中浏览到南胜大神的博客,https://www.cnblogs.com/NanShengBlogs/p/10957489.html 受此启发,特意改装此方法用于批量清理图纸,效果极佳. 详细介绍详 ...

  10. 使用 `ConfigMap` 挂载配置文件

    使用 ConfigMap 挂载配置文件 Intro 有一些敏感信息比如数据库连接字符串之类的出于安全考虑,这些敏感信息保存在了 Azure KeyVault 中,最近应用上了 k8s 部署,所以想把 ...