A. Array and Operations

Time Limit: 1000ms
Memory Limit: 262144KB

64-bit integer IO format: %I64d      Java class name: (Any)

You have written on a piece of paper an array of n positive integers a[1], a[2], ..., a[n] and m good pairs of integers (i1, j1), (i2, j2), ..., (im, jm). Each good pair (ik, jk) meets the following conditions: ik + jk is an odd number and 1 ≤ ik < jk ≤ n.

In one operation you can perform a sequence of actions:

  • take one of the good pairs (ik, jk) and some integer v (v > 1), which divides both numbers a[ik] and a[jk];
  • divide both numbers by v, i. e. perform the assignments: and .

Determine the maximum number of operations you can sequentially perform on the given array. Note that one pair may be used several times in the described operations.

Input

The first line contains two space-separated integers n, m (2 ≤ n ≤ 100, 1 ≤ m ≤ 100).

The second line contains n space-separated integers a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 109) — the description of the array.

The following m lines contain the description of good pairs. The k-th line contains two space-separated integers ik, jk (1 ≤ ik < jk ≤ n, ik + jk is an odd number).

It is guaranteed that all the good pairs are distinct.

Output

Output the answer for the problem.

Sample Input

Input
3 2
8 3 8
1 2
2 3
Output
0
Input
3 2
8 12 8
1 2
2 3
Output
2
思路:最大流;
首先这个可以看成二分图,因为和是奇数,所以两个点的下标一定是一个奇数一个偶数,那么自然想到最大匹配。
要保证次数最多,所以每次除的必定是质因子。所以我们把所有数的质因子打出来,然后每次我们只处理一个质因子。分别建立一个源点,一个汇点,
源点和偶数点连,边权就是这个数有这个数有这个质数的个数。然后汇点就奇数点连,然后再将给你的边连下,跑最大流就行了。
  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<stdlib.h>
5 #include<queue>
6 #include<string.h>
7 #include<map>
8 #include<vector>
9 using namespace std;
10 typedef long long LL;
11 int ans[105];
12 typedef struct node
13 {
14 int x,y;
15 } ss;
16 typedef struct pp
17 {
18 int to;
19 int cap;
20 int rev;
21 } aa;
22 ss bns[105];
23 bool prime[100005];
24 int prime_table[100005];
25 short int an[105][20000];
26 map<int,int>my;
27 vector<pp>vec[105];
28 int level[105];
29 int iter[105];
30 void add(int from,int to,int cap);
31 void bfs(int s);
32 int dfs(int s,int t,int f);
33 int max_flow(int s,int t);
34 const int N = 1e9;
35 int main(void)
36 {
37 int n,m;
38 int i,j;
39 for(i = 2; i <= 1000; i++)
40 {
41 if(!prime[i])
42 {
43 for(j = i; (i*j) <= 100000; j++)
44 {
45 prime[i*j] = true;
46 }
47 }
48 }
49 int cn = 0;
50 for(i = 2; i <= 100000; i++)
51 {
52 if(!prime[i])
53 {
54 my[i] = cn;
55 prime_table[cn++] = i;
56 }
57 }
58 scanf("%d %d",&n,&m);
59 for(i = 1; i <= n; i++)
60 {
61 scanf("%d",&ans[i]);
62 }
63 for(i = 0; i < m; i++)
64 {
65 scanf("%d %d",&bns[i].x,&bns[i].y);
66 if(bns[i].x%2)
67 swap(bns[i].x,bns[i].y);
68 }
69 memset(an,0,sizeof(an));
70 for(i = 1; i <= n; i++)
71 {
72 int x = ans[i];
73 int f = 0;
74 while(x>1&&f < cn)
75 {
76 while(x%prime_table[f]==0)
77 {
78 x /= prime_table[f];
79 an[i][f]++;
80 }
81 f++;
82 if((LL)prime_table[f]*(LL)prime_table[f] > x)
83 break;
84 }
85 if(x>1)
86 {
87 if(!my.count(x))
88 {
89 my[x] = cn;
90 an[i][cn]++;
91 prime_table[cn++] = x;
92 }
93 else
94 {
95 an[i][my[x]]++;
96 }
97 }
98 }
99 int as = 0;
100 for(j = 0; j < cn; j++)
101 {
102 for(i = 0; i <= 100; i++)
103 vec[i].clear();
104 for(i = 2; i <= n; i+=2)
105 {
106 if(an[i][j])
107 {
108 add(0,i,an[i][j]);
109 }
110 }
111 for(i= 1; i <= n; i+=2)
112 {
113 if(an[i][j])
114 {
115 add(i,n+1,an[i][j]);
116 }
117 }
118 for(i = 0; i < m; i++)
119 {
120 add(bns[i].x,bns[i].y,1e9);
121 }
122 as += max_flow(0,n+1);
123 }
124 printf("%d\n",as);
125 return 0;
126 }
127 void add(int from,int to,int cap)
128 {
129 pp nn;
130 nn.to = to;
131 nn.cap = cap;
132 nn.rev = vec[to].size();
133 vec[from].push_back(nn);
134 nn.to = from;
135 nn.cap=0;
136 nn.rev = vec[from].size()-1;
137 vec[to].push_back(nn);
138 }
139 void bfs(int s)
140 {
141 queue<int>que;
142 memset(level,-1,sizeof(level));
143 level[s]=0;
144 que.push(s);
145 while(!que.empty())
146 {
147 int v=que.front();
148 que.pop();
149 int i;
150 for(i=0; i<vec[v].size(); i++)
151 {
152 pp e=vec[v][i];
153 if(level[e.to]==-1&&e.cap>0)
154 {
155 level[e.to]=level[v]+1;
156 que.push(e.to);
157 }
158 }
159 }
160 }
161 int dfs(int s,int t,int f)
162 {
163 if(s==t)
164 return f;
165 for(int &i=iter[s]; i<vec[s].size(); i++)
166 {
167 pp &e=vec[s][i];
168 if(level[e.to]>level[s]&&e.cap>0)
169 {
170 int r=dfs(e.to,t,min(e.cap,f));
171 if(r>0)
172 {
173 e.cap-=r;
174 vec[e.to][e.rev].cap+=r;
175 return r;
176 }
177 }
178 }
179 return 0;
180 }
181 int max_flow(int s,int t)
182 {
183 int flow=0;
184 for(;;)
185 {
186 bfs(s);
187 if(level[t]<0)return flow;
188 memset(iter,0,sizeof(iter));
189 int f;
190 while((f=dfs(s,t,N)) >0)
191 {
192 flow += f;
193 }
194 }
195 }

Array and Operations的更多相关文章

  1. cf498C Array and Operations

    C. Array and Operations time limit per test 1 second memory limit per test 256 megabytes input stand ...

  2. CF498C. Array and Operations [二分图]

    CF498C. Array and Operations 题意: 给定一个长为 n 的数组,以及 m 对下标 (a, b) 且满足 a + b 为奇数,每次操作可以将同一组的两个数同时除以一个公约数 ...

  3. Codeforces Round #284 (Div. 1) C. Array and Operations 二分图最大匹配

    题目链接: http://codeforces.com/problemset/problem/498/C C. Array and Operations time limit per test1 se ...

  4. 网络流(最大流):CodeForces 499E Array and Operations

    You have written on a piece of paper an array of n positive integers a[1], a[2], ..., a[n] and m goo ...

  5. Codeforces 498C Array and Operations(最大流)

    题目是给一些数和<数对>的下标,然后进行操作:对某个<数对>中的两个数同时除以一个都能被它们整除且不等于1的数,要求的就是最多能进行多少次操作. 除数一定是素数,就是要决定某素 ...

  6. codeforcese 498C. Array and Operations 网络流

    题目链接 给n个数, m个数对, 每个数对是两个下标加起来为奇数的两个数.每次操作可以使一个数对中的两个数同时除某个数, 除的这个数是这两个数的任意约数, 问这种操作最多可以做几次.n<100, ...

  7. Codeforces Round #284 (Div. 1) C. Array and Operations 二分图匹配

    因为只有奇偶之间有操作, 可以看出是二分图, 然后拆质因子, 二分图最大匹配求答案就好啦. #include<bits/stdc++.h> #define LL long long #de ...

  8. ZOJ 3427 Array Slicing (scanf使用)

    题意  Watashi发明了一种蛋疼(eggache) 语言  你要为这个语言实现一个 array slicing 函数  这个函数的功能是 有一个数组初始为空  每次给你一个区间[ l, r)  和 ...

  9. Codeforces Round #284 (Div. 1)

    A. Crazy Town 这一题只需要考虑是否经过所给的线,如果起点和终点都在其中一条线的一侧,那么很明显从起点走点终点是不需要穿过这条线的,否则则一定要经过这条线,并且步数+1.用叉积判断即可. ...

随机推荐

  1. 日常Java 2021/10/30

    Java泛型 Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型.泛型的本质是参数化类型,也就是说所操作的数据类型 ...

  2. 日常Java 2021/10/1

    正则表达式 \cx匹配由x指明的控制字符.例如,lcM匹配一个Control-M或回车符.x的值必须为A-Z或a-z之一.否则,将c视为一个原义的'℃'字符.\f匹配--个换页符.等价于\xOc和\c ...

  3. 隐藏状态栏后tableview自动上移20个像素的问题

    最近在开发过程中碰到一个很奇怪的问题,将状态栏隐藏掉之后,页面上的tableView会自动上移20个像素. 这是因为在iOS7.0之后,系统会自动调整scrollView的layout 和 conte ...

  4. What all is inherited from parent class in C++?

    派生类可以从基类中继承: (1)基类中定义的每个数据成员(尽管这些数据成员在派生类中不一定可以被访问): (2)基类中的每个普通成员函数(尽管这些成员函数在派生类中不一定可以被访问): (3)The ...

  5. zabbix之被动模式之编译安装proxy

    #:准备源码包,编译安装 root@ubuntu:/usr/local/src# ls zabbix-4.0.12.tar.gz root@ubuntu:/usr/local/src# tar xf ...

  6. oracle name

    1.db_name 数据库名 SQL> connect xys/manager as sysdba 已连接. SQL> show user USER 为 "SYS" S ...

  7. MySQL 用户权限相关命令

    ##1.创建用户: create user test identified by '123456';##identified后面跟密码 ##2.查询所有用户: select user from mys ...

  8. 【Java基础】transient关键字

    1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过 ...

  9. 【力扣】剑指 Offer 25. 合并两个排序的链表

    输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 示例1: 输入:1->2->4, 1->3->4输出:1->1->2->3-> ...

  10. 为什么企业全面云化需要IT战略支撑和驱动?

    引子:为什么传统企业全面云化一直磨磨唧唧举步维艰? 笔者将企业上云大体上分为几个阶段: 第一个阶段是基础设施虚拟化.即将应用从物理机搬到(lift and shift migration)虚拟机上.基 ...