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 的倍数,且 ...
随机推荐
- 机器学习笔记--KNN算法1
前言 Hello ,everyone. 我是小花.大四毕业,留在学校有点事情,就在这里和大家吹吹我们的狐朋狗友算法---KNN算法,为什么叫狐朋狗友算法呢,在这里我先卖个关子,且听我慢慢道来. 一 K ...
- PHP 数据库抽象层pdo
PDO是PHP数据对象(PHP Data Object)的缩写. pdo就是一个"数据库访问抽象层",作用是统一各种数据库的访问接口,能够轻松地在不同数据库之间进行切换,使得数据库 ...
- emacs最简单入门,只要10分钟
macs最简单入门,只要10分钟 windwiny @2013 无聊的时候又看到鼓吹emacs的文章,以前也有几次想尝试,结果都是玩不到10分钟就退出删除了. 这次硬着头皮,打开几篇文章都看完 ...
- eclipse下遇到 无法解析类型 javax.servlet.http.HttpServletRequest
参考:http://bbs.csdn.net/topics/370187655?page=1 java.lang.Error: 无法解析的编译问题: 无法解析类型 javax.servlet.ht ...
- Java排序算法——选择排序
import java.util.Arrays; //================================================= // File Name : Select_S ...
- 通过Ajax方式上传文件,使用FormData进行Ajax请求
通过传统的form表单提交的方式上传文件: <form id= "uploadForm" action= "http://localhost:8080/cfJAX_ ...
- wordpress数据库表说明
wp系统所用的表不多,那么每张表具体都存些什么?今天给大家介绍一下,希望对你有帮助. wp_commentmeta: 用于保存评论的元信息,在将评论放入回收站等操作时会将数据放入此表,Akismet等 ...
- awk操作数组注意几点
awk的数组跟其他程序设计语言的数组有所不同:1.可以直接在awk中定义数组:2.数组元素的初始值为0或空字符串,除非他们被显示的指定初始化:3.数组可以自动扩展:4.都是关联数组,数字下标也会转成字 ...
- SSLv3 Poodle攻击漏洞检测工具
漏洞编号:CVE-2014-3566 POC如下: import ssl,socket,sys SSL_VERSION={ 'SSLv2':ssl.PROTOCOL_SSLv2, 'SSL ...
- css display 总结
1. 块级元素(display: block) 1.1. 独占一行 1.2. 高度.宽度.行高.顶和底边距 可设置 1.3. 默认宽度 父容器100% 2. 内联元素(display: inline) ...