Contest1789 - 2019年第二阶段我要变强个人训练赛第十二场 问题 H: 计数JS 容斥 JAVA大数

 

题目描述

给定一个长度为n的序列a1..an,求m以内的不能被a1..an中任意一个ai整除的正整数有多少个?

 

输入

第一行两个数n,m
接下来一行n个数,a1..an

 

 

输出

共一个数,即m以内的不能被a1..an中任意一个ai整除的正整数有多少个。

 

样例输入

复制样例数据

3 2015
4 5 6

样例输出

1075

 

提示

对于 30% 的数据,1≤m≤100000
对于另外 30% 的数据,n=3
对于 100% 的数据,1≤n≤20, 1≤m≤1018, 1≤ ai≤109

题解:这就是一个简单的容斥,但两个数取最小公倍数时可能会超long long所以用了下JAVA,第一次用java比赛时过题,爽

import java.math.BigInteger;
import java.text.DateFormatSymbols;
import java.util.Scanner;
 
 
 
public class Main{
    public static BigInteger m;
    public static int n;
    public static BigInteger O = new BigInteger("0");
    public static BigInteger [] a = new BigInteger[22];
    public static BigInteger ans;
    public  static void main(String[] args) {
     
        Scanner cin = new Scanner(System.in);
        n = cin.nextInt();
        m = cin.nextBigInteger();
        for(int i = 1; i <= n; i++)
            a[i] = cin.nextBigInteger();
        ans = m;
        dfs(1, BigInteger.valueOf(0), 0);
         
        System.out.println(ans);
    }
    public static void dfs(int pos, BigInteger res, int sum) {
        //System.out.println();
        if(res.compareTo(m) == 1) return;
        if(pos == n + 1 ) {
            if(sum == 0) return;
            if(sum % 2 == 0) ans=ans.add(m.divide(res));
            else ans=ans.subtract(m.divide(res));
        //  System.out.println(m.divide(res) + " " + res+" "+ans);
            return;
        }
        dfs(pos + 1, res, sum);
        BigInteger temp = new BigInteger("0");
        BigInteger t = new BigInteger("0");
        if(res.compareTo(O) == 0) temp = a[pos];
        else {
            t = res.gcd(a[pos]);
            temp =  res.multiply(a[pos]);
            temp = temp.divide(t);
        //  System.out.println(sum + " " + temp+" "+a[pos]+" "+res);
        }
         
        dfs(pos + 1, temp, sum + 1);
    }
     
}

 

你可能感兴趣的:(容斥原理,JAVA)