能被整除的数(容斥原理)

思路:

(1)需求:求对于1~n中至少能被p1~pm至少1个整除的数的个数,由于都是质数,彼此互质,不需要进行质因子分解,根据容斥原理,

                        res = n/p1 + n/p2 +... + n/pm - n /(p1p2) - n/(p1p3) - ...;

显然只需要讨论p1~pm所有组合形式t,如果小于等于n:

  1. 如果是奇数个质数组成,则加等于n/t,否则减等于n/t;

最终结果即为1~n之间的所有至少能被p1~pm之间1个数整除的数的个数。

(2)注意用二进制讨论组合方式时,不能全零,全零即为1,不满足至少被其中一个整除。

代码:

#include

using namespace std;
const int N = 20,M = 1 << N;
typedef long long LL;

LL p[N];

int main()
{
    int n,m;
    cin >> n >> m;
    
    for(int i = 0;i < m;i ++)cin >> p[i];
    
    LL res = 0;
    for(int i = 1;i < (1 << m);i ++)
    {
        LL t = 1,cnt = 0;
        for(int j = 0;j < m;j ++)
        {
            if(i>>j &1 == 1)
            {
                cnt ++;
                t *= p[j];
                if(t > n) break;
            }
        }
        

        if(t <= n)
        {
            if(cnt %2 == 0) res -= n/t;
            else res += n/t;
        }
    }
    
    cout << res << endl;
    
    return 0;
}

你可能感兴趣的:(算法,c++,数据结构)