F - Prime Independence LightOJ1356

F - Prime Independence

Time Limit: 2000/1000 MS (Java/Others)      Memory Limit: 128000/64000 KB (Java/Others)

Submit Status

Problem Description

A set of integers is called prime independent if none of its member is a prime multiple of another member. An integer a is said to be a prime multiple of b if,

a = b x k (where k is a prime [1])

So, 6 is a prime multiple of 2, but 8 is not. And for example, {2, 8, 17} is prime independent but {2, 8, 16} or {3, 6} are not.

Now, given a set of distinct positive integers, calculate the largest prime independent subset.

Input

Input starts with an integer T (≤ 20), denoting the number of test cases.

Each case starts with an integer N (1 ≤ N ≤ 40000) denoting the size of the set. Next line contains N integers separated by a single space. Each of these N integers are distinct and between 1 and 500000 inclusive.

Output

For each case, print the case number and the size of the largest prime independent subset.

Sample Input

3
5
2 4 8 16 32
5
2 3 4 6 9
3
1 2 3

Sample Output

Case 1: 3
Case 2: 3
Case 3: 2

Hint

An integer is said to be a prime if it‘s divisible by exactly two distinct integers. First few prime numbers are 2, 3, 5, 7, 11, 13, ...
Dataset is huge, use faster I/O methods.

  1 #include <stdio.h>
  2 #include <queue>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <vector>
  7 #include <map>
  8 #include <set>
  9 #include <ctime>
 10 #include <cmath>
 11 #include <cctype>
 12 #include <iostream>
 13 using namespace std;
 14 typedef long long LL;
 15 const int N=5*1e5+10;
 16 const int INF=0x3f3f3f3f;
 17 const int maxn=40010;
 18 int cas=1,T;
 19 int id[N];
 20 struct maxMacth
 21 {
 22     int n;
 23     int vm[N],um[N];
 24     bool vis[N];
 25     vector<int>g[N];
 26     int dx[N],dy[N],dis;
 27     void init(int num)
 28     {
 29         n=num;
 30         memset(vm,-1,sizeof(vm));
 31         memset(um,-1,sizeof(um));
 32         for(int i=0;i<=n;i++)
 33             g[i].clear();
 34     }
 35     void inserts(int u, int v)
 36     {
 37         g[u].push_back(v);
 38     }
 39     bool searchP()
 40     {
 41         queue<int>q;
 42         dis=INF;
 43         memset(dx,-1,sizeof(dx));
 44         memset(dy,-1,sizeof(dy));
 45         for(int i=1;i<=n;i++)
 46             if(um[i]==-1)
 47             {
 48                 q.push(i);
 49                 dx[i]=0;
 50             }
 51         while(!q.empty())
 52         {
 53             int u=q.front();q.pop();
 54             if(dx[u]>dis)  break;
 55             for(int i=0;i<g[u].size();i++)
 56             {
 57                 int v = g[u][i];
 58                 if(dy[v]==-1)
 59                 {
 60                     dy[v]=dx[u]+1;
 61                     if(vm[v]==-1)  dis=dy[v];
 62                     else
 63                     {
 64                         dx[vm[v]]=dy[v]+1;
 65                         q.push(vm[v]);
 66                     }
 67                 }
 68             }
 69         }
 70         return dis!=INF;
 71     }
 72     bool dfs(int u)
 73     {
 74         for(int i=0;i<g[u].size();i++)
 75         {
 76             int v = g[u][i];
 77             if(!vis[v]&&dy[v]==dx[u]+1)
 78             {
 79                 vis[v]=1;
 80                 if(vm[v]!=-1&&dy[v]==dis) continue;
 81                 if(vm[v]==-1||dfs(vm[v]))
 82                 {
 83                     vm[v]=u;um[u]=v;
 84                     return 1;
 85                 }
 86             }
 87         }
 88         return 0;
 89     }
 90     int maxMatch()
 91     {
 92         int res=0;
 93         while(searchP())
 94         {
 95             memset(vis,0,sizeof(vis));
 96             for(int i=1;i<=n;i++)
 97               if(um[i]==-1&&dfs(i))  res++;
 98         }
 99         return res;
100     }
101 }MM;
102 int pn,p[N],vis[N],e[N];
103 void init()
104 {
105     memset(vis,0,sizeof(vis));
106     memset(e,0,sizeof(e));
107     pn=0;
108     for(int i=2;i<N;i++) if(!vis[i])
109     {
110         p[pn++]=i;
111         for(int j=i;j<N;j+=i)
112         {
113             vis[j]=1;
114             int x=j;
115             while(x%i==0) x/=i,e[j]++;
116         }
117     }
118 }
119 int main()
120 {
121 //    freopen("1.in","r",stdin);
122 //    freopen("1.out","w",stdout);
123     init();
124     scanf("%d",&T);
125     while(T--)
126     {
127         int n;
128         scanf("%d",&n);
129         memset(id,0,sizeof(id));
130         for(int i=1,x;i<=n;i++) scanf("%d",&x),id[x]=i;
131         MM.init(n);
132         for(int i=1;i<N;i++) if(id[i])
133         {
134             for(int j=0;i*p[j]<N && j<pn;j++) if(id[i*p[j]])
135             {
136                 if(e[i]&1)
137                     MM.g[id[i]].push_back(id[i*p[j]]);
138                 else
139                     MM.g[id[i*p[j]]].push_back(id[i]);
140             }
141         }
142         printf("Case %d: %d\n",cas++,n-MM.maxMatch());
143 //        printf("Case %d: %d\n",cas++,n-MM.maxMatch()/2);
144 //        cerr<<clock()<<"ms\n";
145     }
146     return 0;
147 }

solve.cpp

题解:

用筛法将满足a×p=b(p为质数)的a,b建一条边(注意方向),然后跑二分图最大匹配,也可以直接建两条边,然后结果除以二
答案为:点数-最大匹配

时间: 2024-11-05 15:51:18

F - Prime Independence LightOJ1356的相关文章

LightOJ 1356 Prime Independence (素数 二分图)

Prime Independence Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice LightOJ 1356 Description A set of integers is called prime independent if none of its member is a prime multiple of another member. A

F - Prime Path POJ 3126 筛选素数+bfs

F - Prime Path Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3126 Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have t

Light OJ 1356 Prime Independence 最大独立集+素数筛选

题目来源:Light OJ 1356 Prime Independence 题意:给你n个数 选出最多的数构成一个集合使得任何2个数不是另外一个数的质数倍 x!=k*y 思路:矛盾的2个数连边 并且所有数分成质因子数为奇数和偶数两部分 以质因子奇偶不同构建二分图 同奇或者同偶的数一定不是另外一个数的质数倍 判断矛盾 首先对每个数因子分解 例如x 有a1个p1质因子 a2个p2质因子...an个pn质因子 x的质因子个数为a1+a2+...+an 记为sum 判断是否存在x/p1  x/p2 ..

LightOJ 1356 Prime Independence 二分图最大独立集,HK算法

这个题唯一需要说的就是普通的匈牙利算法是O(nm)的,过不了 然后HK算法可以O(n^0.5m),这个算法可以每次找很多同样长度的最短增广路 分析见:http://www.hardbird.net/lightoj-1356-prime-independence%E6%9C%80%E5%A4%A7%E7%8B%AC%E7%AB%8B%E9%9B%86-hopcroft-carp%E7%AE%97%E6%B3%95/ #include <cstdio> #include <iostream&

F - Prime Path

题目大意: 素数路径 估计看数据就明白这道题什么意思了......给两个素数,都是四位数的素数,并且没有前导0,现在需要经过一种变换把一个素数转换成另一个,当然这种转换是有规则的,规则就是每次只能改变这个四位数的其中一位数字,当然改变后的数字也得是素数,问最少的改变次数是多少...... 貌似还是广搜..............................................................................................不过做起来

Prime Independence LightOJ - 1356 (HK 最大独立集 板子)

题意:给你一组数,求一个最大的子集,要求任意两个的倍数都不是素数倍 题解:将每一个数按照质因数奇偶分开,同为奇偶的肯定是合数倍,在奇偶中刚好是素数倍的建边,跑二分图最大独立集,n - 匹配数就是答案 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<sstream> #include<cmath> #include<

Prime Independence

题意: 对于给定集合,求解最大的子集合,使得集合内两两之商不为质数. 解法: 考虑对于每一个数字分解质因数可以得到 $O(nloglogNUM)$ 条两个数字不可以出现在同一集合的信息. 同时发现一条代表冲突的边必然是联结一个由奇数个质数连乘构成的数字和一个由偶数个质数连乘构成的数字. 是一个二分图,考虑最大独立集即可. #include <bits/stdc++.h> const int N = 100010; using namespace std; int n,timnow; int p

LightOJ 1356 Prime Independence(质因数分解+最大独立集+Hopcroft-Carp)

http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1356 题意: 给出n个数,问最多能选几个数,使得该集合中的任意两个数中其中一个数不是另一个质数倍. 思路: 二分图的最大独立集. 那么怎么建图呢?我们按照质因数的奇偶性来分成两部分建图,如果两个数是质数倍的关系,那么就连边,最后最大独立集=点数-最大匹配. 对每个数进行质因数分解,存储每个质因数和质因数的总数,比如说P,质因数为x1,x2,x3...接下来

关于$f(x)=\int_0^x\left|\sin\frac1t\right|\text dt$求导的问题

??首先,我们考虑\(f(x)\)在\(\mathbb R\)上都是定义的.根据定义,显然有\(f(0)=0\):其次,对于\(x\neq0\),不妨先设\(x\gt0\),则有在\(t\rightarrow\frac1t\)的积分变换下为 \[0<f(x)=\int_0^x\left|\sin\frac1t\right|\text dt=\int_{\frac1x}^{+\infty}\frac{\left|\sin t\right|}{t^2}\text dt\le\int_{\frac1x