Array and Operations

A. Array and Operations

Time Limit: 1000ms

Memory Limit: 262144KB

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

Submit Status

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 28 3 81 22 3

Output

0

Input

3 28 12 81 22 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 }
				
时间: 2024-11-06 15:17:02

Array and Operations的相关文章

「CodeForces-498C」Array and Operations(数论+网络流)

「CodeForces-498C」Array and Operations给定n个点和m个边集,每次操作可以将相连边的两个点值同时除以一个公约数,问最大操作次数 题意 给定一个长为$n$的数组,以及$m$对下标为$(a,b)$的点对,且满足下标a+b为奇数(即奇数点只与偶数点匹配),每次操作可以将同一组的两个数同时除以一个公约数,问最多能进行多少次操作. 解法 显然题目所给的是一个二分图. 对于每个质因数分开考虑.对于奇数点,向源点连接一个容量为该因子个数的边:对于偶数点,则向汇点建立一个容量为

网络流(最大流):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 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 < j

CodeForces 498C Array and Operations(最大流)

题目是给一些数和<数对>的下标,然后进行操作:对某个<数对>中的两个数同时除以一个都能被它们整除且不等于1的数,要求的就是最多能进行多少次操作. 除数一定是素数,就是要决定某素数要除哪些<数对>使除的次数最多, ik + jk is an odd number 可以想到这个是个二分图,数最多100个,然后就用最大流做了. 有了POJ2516的经验之后,马上想到,素数是独立的,进行若干次最大流而不是拆若干点跑最大流(10^9大概最多拆30个点吧).. 然后我还是没AC,因

codeforces 498C Array and Operations 网络流

传送门:cf 498C 给定一个长度为n的数组,已经m组下标对应关系(下标之和为奇数),现在可以对m组对应关系中的数同除一个大于1的整数,问最多能进行多少次这样的操作 要操作次数最大,每次处理的时候应该除质数. 下标之和为奇数,不难发现它构成了一张二分图. 枚举sqrt(10^9)的质数,找出n个数中各有多少个这样的质数k,然后建立对应的图,跑网络流最大流即可. /****************************************************** * File Name

498C - Array and Operations 质因子分解+最大流

题目中说每一个good pair<u,v> 都满足(u+v)%2 == 1,即一个奇数,一个偶数. 首先我们要拿出一原点S,汇点T,S联到所有的num[odd]的质因子上,T联到所有的num[even]的质因子上,边的流量为num[i]中相应质因子的个数. 再根据给出的<u,v>,假设u为奇数,则从u的质因子上联到相等的v的质因子上,流量为INF. 丢到模板里跑一遍就好了. #include <algorithm> #include <iostream> #

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

因为只有奇偶之间有操作, 可以看出是二分图, 然后拆质因子, 二分图最大匹配求答案就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #defin

ZOJ 3427 Array Slicing (scanf使用)

题意  Watashi发明了一种蛋疼(eggache) 语言  你要为这个语言实现一个 array slicing 函数  这个函数的功能是 有一个数组初始为空  每次给你一个区间[ l, r)  和一些数   你要输出数组中下标在[l, r) 之间的数  然后删除这些数  然后把给你的那些数插入到数组的下标为 l 的位置 签到模拟题  一直没看懂题意  看了Watashi的scanf高端用法  弱到连scanf都不会用了  强行到cpp预习了一下  先记录一下那些并不了解的scanf用法吧 i

联系人提供程序

联系人提供程序是一个强大而又灵活的 Android 组件,用于管理设备上有关联系人数据的中央存储库. 联系人提供程序是您在设备的联系人应用中看到的数据源,您也可以在自己的应用中访问其数据,并可在设备与在线服务之间传送数据. 提供程序储存有多种数据源,由于它会试图为每个联系人管理尽可能多的数据,因此造成其组织结构非常复杂. 为此,该提供程序的 API 包含丰富的协定类和接口,为数据检索和修改提供便利. 本指南介绍下列内容: 提供程序基本结构 如何从提供程序检索数据 如何修改提供程序中的数据 如何编

Data Modeling for MVC Applications

原文: Data Modeling for MVC Applications 模型-视图-控制器(MVC)是程序开发的主流范式.我们来看看Dojo为开发MVC的应用提供了些什么.我们将学习如何利用Dojo的stores对象与为模型提供的状态对象,以及如何在模型级别之上建立模型化的视图与控制器. MVC应用的数据模型 MVC是应用开发的主流范式.MVC为使代码有组织性,易管理性对关注点做了分层.Dojo是重度基于MVC法则的,并为构建MVC架构的应用提供了强大的帮助.一个设计良好的MVC应用的基石