【POJ】1091 跳蚤

题意:有n张卡片,每张上的值可以相同,每张上的值不超过m,第n+1张为m。设k[i]为任意整数,a[i]为第i张卡片的值,那么问∑k[i]*a[i]=1的a[i]有多少种(0<=i<=n)。

有式子可得n+1个数线性无关,即最大公约数必然等于1。

总数是m^n,只要求得最大公约数不等于1的种数,就能得到答案。

先对m分解素因子,例如12,有2,3。

是2的倍数的有6个:2 4 8 6 10 12。

是3的倍数的有4个:3 6 9 12。

是6的倍数的有2个:6 12。

所以与12不互质的有6+4-2=8个。

import java.util.*;
import java.math.*;

public class Main {
    public static int cnt;
    public static int fac[] = new int[110];

    public static void Factor(int n) {
        int i, tmp;
        cnt = 0;
        tmp = (int) (Math.sqrt((double) n) + 1e-8);
        for (i = 2; i <= tmp; i++) {
            if (n % i == 0) {
                fac[cnt++] = i;
                while (n % i == 0)
                    n /= i;
            }
        }
        if (n > 1)
            fac[cnt++] = n;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        BigInteger ans, tmp, tot;
        int n, m, i, j, k, t;
        while (in.hasNext()) {
            n = in.nextInt();
            m = in.nextInt();
            Factor(m);
            ans = BigInteger.ZERO;
            tot = BigInteger.valueOf(m).pow(n);
            for (i = 1; i < (1 << cnt); i++) {
                tmp = BigInteger.ONE;
                t = i;
                for (j = k = 0; t != 0; t >>= 1, j++) {
                    if (t % 2 == 1) {
                        k++;
                        tmp = tmp.multiply(BigInteger.valueOf(fac[j]));
                    }
                }
                tmp = BigInteger.valueOf(m).divide(tmp);
                tmp = tmp.pow(n);
                if (k % 2 == 1)
                    ans = ans.add(tmp);
                else
                    ans = ans.subtract(tmp);
            }
            System.out.println(tot.subtract(ans));
        }
    }
}
原文地址:https://www.cnblogs.com/DrunBee/p/2674602.html