zoukankan      html  css  js  c++  java
  • F

    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
    ",cas++,n-MM.maxMatch());
    143 //        printf("Case %d: %d
    ",cas++,n-MM.maxMatch()/2);
    144 //        cerr<<clock()<<"ms
    ";
    145     }
    146     return 0;
    147 }
    solve.cpp

    题解:

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

  • 相关阅读:
    1.33 (累积互素数)
    1.33 (过滤累积和 求区间内所有素数之和)
    1.32 (更高层次的抽象! 乘法与加法本来就是一回事)
    1.31 (另一种求圆周率的算法)
    1.30 (递归的sum变迭代)
    习题1.29 (积分方法的优化---simpson规则)
    1.3.1 (对过程的抽象)
    SICP习题 1.23(素数查找的去偶数优化)
    SICP习题 1.22(素数)
    pom.xml
  • 原文地址:https://www.cnblogs.com/cdyboke/p/7010539.html
Copyright © 2011-2022 走看看