hdu4497 GCD and LCM ——素数分解+计数

August 26, 2013
数学题

link:http://acm.hdu.edu.cn/showproblem.php?pid=4497

如果G%L != 0,说明一定无解。

把K = G / L质数分解,G / L = p1^t1 * p2^t2 * p3^t3 * ……;同时 x/= L, y/= L, z/=L,不影响结果。

假设三个数字的质数分解是:

x = p1^i1 * p2^i2 * p3^i3 * ……

y = p1^j1 * p2^j2 * p3^j3 * ……

z = p1^k1 * p2^k2 * p3^k3 * ……

要保证x, y, z互质,并且lcm(x, y, z) = K, 那么对于p1来说,i1, j1, k1里面一定有一个是0,并且一定有一个是t1,所以有3种情况:

0 0 t1 有3种

t1 t1 0 有3种

t1 0 1~t1-1 有(t1-1)*6种

一共是6*t1种。

根据乘法原理,总的种数是:6*t1 + 6*t2 + ……

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <queue>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <functional>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <numeric>
#include <cassert>
#include <ctime>
#include <iterator>
const int INF = 0x3f3f3f3f;
const int dir[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
using namespace std;
#define LL __int64
const int MAX=100002;
int prime[MAX];
bool flag[MAX];
int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin );
    #endif // ONLINE_JUDGE
    int t;
    scanf("%d", &t);
        memset(flag, true, sizeof(flag));
    int cnt = 0;
    for (int i = 2; i * i <= 100000; ++i)
    {
            if (flag[i])
                for (int j = i*2; j <= 100000; j+=i)
                    flag[j] = false;
    }
        for (int i = 2; i <= 100000; ++i) if(flag[i]) prime[cnt++] = i;
    while (t--)
    {
        int G, L;
        scanf("%d%d", &G, &L);
        int ans = 1;
        if (L % G)
        {
            printf("0\n");
            continue;
        }
        int K = L / G, S = K;
        for (int i = 0; i < cnt; ++i)
        {
            if (prime[i] * prime[i] > S) break;
            if (K%prime[i] == 0)
            {
                int touch = 0;
                while (K%prime[i] == 0)
                {
                    K /= prime[i]; touch++;
                }
                ans *= touch * 6;
            }
        }
        if (K != 1) ans *= 6;
        printf("%d\n", ans);
    }

    return 0;
}

当你不明白一个东西的时候,就他妈的别用。

比如,ios::sync_with_stdio(false); 这货表示消除cin, cout 的输入输出缓存,如果混合使用cout, printf的时候,同时用cout的时候也用了endl(表示清空缓存),注意,在程序开头,已经打开消除cin, cout 的输入输出缓存这个开关了,这里又清空缓存,不是矛盾嘛!有意思的是,如果用c++交就会AC,用G++交就会WA,本来我想要输入输出快一点,结果弄巧成拙了。

还有一定要想清楚为什么要有71行。

参考:

https://www.byvoid.com/blog/fast-readfile/

http://www.cnblogs.com/cszero/archive/2012/02/11/Zero0ne.html

以后多注意这些东西。

嗨,中村。

comments powered by Disqus