BZOJ4514——[Sdoi2016]数字配对
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define llinf 2000000000000000000
#define inf 2147483647
#define for1(i, x, y) for(LL i = (x); i <= (y); i ++)
#define for2(i, x, y) for(LL i = (x); i >= (y); i --)
namespace mcmf{
LL s, t;
struct Edge{
LL u, v, cap, flow;
LL cost;
LL next;
} G[250010];
LL tot;
LL head[3000];
LL inq[3000];
LL d[3000];
LL p[3000];
LL a[3000];
inline void init(){
memset(head, -1, sizeof(head));
tot = -1;
}
inline void add(LL u, LL v, LL w, LL cost){
G[++ tot] = (Edge){u, v, w, 0, cost, head[u]};
head[u] = tot;
G[++ tot] = (Edge){v, u, 0, 0, -cost, head[v]};
head[v] = tot;
return;
}
inline bool BellmanFord(LL& flow, LL& cost){
for(LL i = s; i <= t; i ++) d[i] = -llinf;
memset(inq, 0, sizeof(inq));
d[s] = 0;
inq[s] = 1;
p[s] = 0;
a[s] = inf;
queue<LL> Q;
Q.push(s);
while(!Q.empty()){
LL u = Q.front(); Q.pop();
inq[u] = 0;
for(LL i = head[u]; i != -1; i = G[i].next){
Edge& e = G[i];
if(e.cap > e.flow && d[e.v] < d[u] + e.cost){
d[e.v] = d[u] + e.cost;
p[e.v] = i;
a[e.v] = min(a[u], e.cap - e.flow);
if(!inq[e.v]){
Q.push(e.v);
inq[e.v] = 1;
}
}
}
}
if(d[t] == -llinf) return false;
flow += a[t];
cost += d[t] * (LL)a[t];
if(cost < 0){
cost -= d[t] * (LL)a[t];
flow -= a[t];
flow += cost / -d[t];
return false;
}
LL u = t;
while(u != s){
G[p[u]].flow += a[t];
G[p[u] ^ 1].flow -= a[t];
u = G[p[u]].u;
}
return true;
}
inline LL Minflow(){
LL flow = 0; LL cost = 0;
while(BellmanFord(flow, cost));
return flow;
}
}
LL a[100010], b[100010], c[100010];
LL prime[100010], tot; bool vis[100010];
LL cnta[100010];
inline LL read(){ // getchar较快于scanf,更快的还有fread,不会23333
char ch = getchar(); LL x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline LL llread(){
char ch = getchar(); LL x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void init_prime(){
for1(i, 2, 100000){
if(!vis[i]) prime[++ tot] = i;
for1(j, 1, tot){
if(i * prime[j] > 100000) break;
vis[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
inline bool is_prime(LL x){
if(x <= 100000) return 1 - vis[x];
LL t = sqrt(x);
for1(i, 1, tot){
if(prime[i] > t) break;
if(x % prime[i] == 0) return false;
}
return true;
}
int main(){
LL n = read();
for1(i, 1, n) a[i] = llread();
for1(i, 1, n) b[i] = llread();
for1(i, 1, n) c[i] = llread();
mcmf::init();
init_prime();
for1(i, 1, n){
LL t = sqrt(a[i]);
LL o = a[i];
for1(j, 1, tot){
if(prime[j] > t) break;
while(o % prime[j] == 0) o /= prime[j], cnta[i] ++;
if(o == 1) break;
}
if(o != 1) cnta[i] ++;
}
mcmf::s = 0; mcmf::t = n + 1;
for1(i, 1, n){
if(cnta[i] & 1) mcmf::add(0, i, b[i], 0);
else mcmf::add(i, n + 1, b[i], 0);
}
for1(i, 1, n) if(cnta[i] & 1){
for1(j, 1, n) if(!(cnta[j] & 1)){
if(a[i] % a[j] != 0 && a[j] % a[i] != 0) continue;
if(a[i] % a[j] == 0 && is_prime(a[i] / a[j])) mcmf::add(i, j, inf, c[i] * c[j]);
else if(a[j] % a[i] == 0 && is_prime(a[j] / a[i])) mcmf::add(i, j, inf, c[i] * c[j]);
}
}
printf("%lld", mcmf::Minflow());
return 0;
}
BZOJ4514——[Sdoi2016]数字配对的更多相关文章
- bzoj4514 [Sdoi2016]数字配对
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...
- BZOJ4514[Sdoi2016]数字配对——最大费用最大流
题目描述 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci ...
- bzoj4514 [Sdoi2016]数字配对(网络流)
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...
- [bzoj4514][SDOI2016]数字配对——二分图
题目描述 传送门 题解: 这个题真的是巨坑,经过了6个WA,2个TLE,1个RE后才终于搞出来,中间都有点放弃希望了... 主要是一定要注意longlong! 下面开始说明题解. 朴素的想法是: 如果 ...
- BZOJ4514 [Sdoi2016]数字配对 【费用流】
题目 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×c ...
- bzoj4514: [Sdoi2016]数字配对--费用流
看了一眼题目&数据范围,觉得应该是带下界的费用流 原来想拆点变成二分图,能配对的连边,跑二分图,可行性未知 后来看到另外一种解法.. 符合匹配要求的数要满足:质因子的个数相差为1,且两者可整除 ...
- bzoj4514: [Sdoi2016]数字配对(费用流)
传送门 ps:费用流增广的时候费用和流量打反了……调了一个多小时 每个数只能参与一次配对,那么这就是一个匹配嘛 我们先把每个数分解质因数,记质因子总个数为$cnt_i$,那如果$a_i/a_j$是质数 ...
- 【bzoj4514】: [Sdoi2016]数字配对 图论-费用流
[bzoj4514]: [Sdoi2016]数字配对 好像正常的做法是建二分图? 我的是拆点然后 S->i cap=b[i] cost=0 i'->T cap=b[i] cost=0 然后 ...
- 【BZOJ4514】[Sdoi2016]数字配对 费用流
[BZOJ4514][Sdoi2016]数字配对 Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ...
随机推荐
- Linux Canbus调试笔记
STM32之CAN---错误管理分析 牛人博客 http://blog.csdn.net/flydream0/article/details/8161418 CAN总线在嵌入式Linux下驱 ...
- TeamViewer12.0.71503(远程控制软件)精简版单文件企业版介绍
TeamViewer 是一款能在任何防火墙和 NAT 代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamViewer 即可 ...
- c#正则表达式2
System.Text.RegularExpressions.Regex ___rx = new System.Text.RegularExpressions.Regex(@""& ...
- 枚举类型Enum
包java.dataStructure中,文件名Enum_demo.java 在JDK5中引入了一个新的关键字——enum,可以直接定义枚举类型 在申明枚举类的时候,也可以申明属性.方法和构造函数,但 ...
- codeforces 712A. Memory and Crow
题目链接:http://codeforces.com/problemset/problem/712/A 题目大意: 给你一个数字系列,求其满足条件的一个序列. 条件为: ai = bi - bi + ...
- 使用 Object.create 创建对象,super 关键字,class 关键字
ECMAScript 5 中引入了一个新方法:Object.create().可以调用这个方法来创建一个新对象.新对象的原型就是调用 create 方法时传入的第一个参数: var a = {a: 1 ...
- window.onscroll页面滚动条滚动事件
用途一:"返回顶部": window.onscroll = function(){ var t = document.documentElement.scrollTop || do ...
- Jexus-5.6.3使用详解
一.Jexus Web Server配置 在 jexus 的工作文件夹中(一般是"/usr/jexus")有一个基本的配置文件,文件名是"jws.conf".j ...
- 常用JS效果 不断进步贴 不停更新~ 纪念用~
常用效果 JS 都是Jquery 没有特殊说明 1.选项卡 用的JQuery 以后学好点再来对比 看下 /* * @parent 最外层父级元素 * @EventElement 触发事件元素 ...
- [转]Ubuntu 16.04建议安装
Ubuntu 16.04发布了,带来了很多新特性,同样也依然带着很多不习惯的东西,所以装完系统后还要进行一系列的优化. 1.删除libreoffice libreoffice虽然是开源的,但是Java ...