题目链接:

codeforces 222C


题目大意:

给出两个集合,第一个集合数的乘积是分子,第二个集合的数的乘积是分母,要求够造一个同样的集合,但是得到的分数是化简过的。


题目分析:

-首先筛出素数,然后处理每一集合,统计每个集合的各个质因数出现的次数,然后每个质因数减去两个集合较小的那个的质因数的个数,然后利用每个集合约分后剩下的质因数构造出合法解即可,采用的对于每个数,贪心的除去被约分掉的部分。
- 筛取质因数不能采用(√n)的方法会超时,构造时也不行,有一些利用数的性质的小的优化。


AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 100007

using namespace std;

typedef long long LL;

int a[MAX],b[MAX],n,m,mark[MAX*100];
int num1[MAX*100],num2[MAX*100];

void init ( )
{
    memset ( mark , 0, sizeof ( mark ) );
    mark[1] = mark[0] = 1;
    LL lim = 1e7;
    for ( LL i = 2 ; i <= lim; i++ )
    {
        if ( mark[i] ) continue;
        for ( LL j = i*i ; j <= lim; j+=i )
        {
            mark[j] = 1;
        }
    }
}

void _handle ( int num , int cnt[] )
{
    for ( int i = 2 ; i*i <= num &&mark[num];i++)
        while ( num%i == 0 )
        {
            cnt[i]++;
            num /= i;
        }
    if ( num > 1 ) cnt[num]++;
}

int _make ( int num , int cnt[])
{
    int ret = 1;
    for ( int i = 2 ; i*i <= num && mark[num];i++)
        while ( num%i == 0 )
        {
            if ( cnt[i] )
            {
                cnt[i]--;
                ret *= i;
            }
            num /= i;
        }
    if ( num > 1 && cnt[num] ) 
    {
        cnt[num]--;
        ret *= num;
    }
    return ret;
}

int main ( )
{
    init ( );
    while ( ~scanf ( "%d%d" , &n , &m ) )
    {
        memset ( num1 , 0 , sizeof ( num1 ) );
        memset ( num2 , 0 , sizeof ( num2 ) );
        int maxn = 0;
        for ( int i = 0 ; i < n ; i++ )
        {
            scanf ( "%d" , &a[i] );
            _handle ( a[i] , num1 );
            maxn = max ( a[i] , maxn );
        }
        for ( int i = 0 ; i < m ; i++ )
        {
            scanf ( "%d" , &b[i] );
            _handle ( b[i] , num2 );
            maxn = max ( b[i] , maxn );
        }
        for ( int i = 0 ; i <= maxn ; i++ )
        {
            int temp = min ( num1[i] , num2[i] );
            num1[i] -= temp;
            num2[i] -= temp;
        }
        printf ( "%d %d\n" , n , m );
        for ( int i = 0 ; i < n ; i++ )
            printf ( "%d " ,  _make ( a[i] , num1 ) );
        puts ("");
        for ( int i = 0 ; i < m ; i++ )
            printf ( "%d " ,  _make ( b[i] , num2 ) );
        puts ("");
    }
}