CodeForces-498C.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <limits>
  4. #include <queue>
  5. #include <utility>
  6. #include <vector>
  7. using namespace std;
  8. struct Dinic {
  9. struct Edge { int to, reverse, capacity; };
  10. vector<vector<Edge>> g;
  11. vector<int> level, cursor;
  12. explicit Dinic(int n) : g(n), level(n), cursor(n) {}
  13. void add_edge(int u, int v, int capacity) {
  14. Edge a{v, static_cast<int>(g[v].size()), capacity};
  15. Edge b{u, static_cast<int>(g[u].size()), 0};
  16. g[u].push_back(a); g[v].push_back(b);
  17. }
  18. bool bfs(int source, int sink) {
  19. fill(level.begin(), level.end(), -1); queue<int> q;
  20. level[source] = 0; q.push(source);
  21. while (!q.empty()) {
  22. int u = q.front(); q.pop();
  23. for (const Edge &e : g[u]) if (e.capacity > 0 && level[e.to] == -1) {
  24. level[e.to] = level[u] + 1; q.push(e.to);
  25. }
  26. }
  27. return level[sink] != -1;
  28. }
  29. int dfs(int u, int sink, int pushed) {
  30. if (u == sink) return pushed;
  31. for (int &i = cursor[u]; i < static_cast<int>(g[u].size()); ++i) {
  32. Edge &e = g[u][i];
  33. if (e.capacity > 0 && level[e.to] == level[u] + 1) {
  34. int flow = dfs(e.to, sink, min(pushed, e.capacity));
  35. if (flow) {
  36. e.capacity -= flow; g[e.to][e.reverse].capacity += flow; return flow;
  37. }
  38. }
  39. }
  40. return 0;
  41. }
  42. int max_flow(int source, int sink) {
  43. int answer = 0, flow;
  44. while (bfs(source, sink)) {
  45. fill(cursor.begin(), cursor.end(), 0);
  46. while ((flow = dfs(source, sink, numeric_limits<int>::max() / 4)) > 0) answer += flow;
  47. }
  48. return answer;
  49. }
  50. };
  51. int main() {
  52. ios::sync_with_stdio(false);
  53. cin.tie(nullptr);
  54. int n, m; cin >> n >> m;
  55. vector<int> a(n), original(n), primes;
  56. for (int &x : a) cin >> x;
  57. original = a;
  58. for (int x : a) {
  59. for (int p = 2; 1LL * p * p <= x; ++p) if (x % p == 0) {
  60. primes.push_back(p); while (x % p == 0) x /= p;
  61. }
  62. if (x > 1) primes.push_back(x);
  63. }
  64. sort(primes.begin(), primes.end()); primes.erase(unique(primes.begin(), primes.end()), primes.end());
  65. vector<pair<int, int>> pairs(m);
  66. for (auto &[u, v] : pairs) { cin >> u >> v; --u; --v; if (u % 2 == 1) swap(u, v); }
  67. int answer = 0, source = n, sink = n + 1;
  68. for (int prime : primes) {
  69. Dinic flow(n + 2); vector<int> exponent(n);
  70. for (int i = 0; i < n; ++i) {
  71. int x = original[i];
  72. while (x % prime == 0) ++exponent[i], x /= prime;
  73. if (i % 2 == 0) flow.add_edge(source, i, exponent[i]);
  74. else flow.add_edge(i, sink, exponent[i]);
  75. }
  76. for (auto [u, v] : pairs) flow.add_edge(u, v, 1'000'000);
  77. answer += flow.max_flow(source, sink);
  78. }
  79. cout << answer << '\n';
  80. }