容斥定理 njust1923 triple

来源:互联网 发布:趣味编程100例 编辑:程序博客网 时间:2024/06/05 00:10

传送门:点击打开链接

题意:给n,m,求1~n中选3个不相等的数出来,3个数的最大公约数等于m的组合数有多少。(n, m <= 1e5)

思路:我们很容易通过组合,可以求出,3个数的最大公约数是i的倍数的组合数,即C(n/i, 3)

但是,我们需要的是最大公约数是m的组合数,所以我们先通过求出m的倍数的,然后把其他倍数的个数减去就行了

所以我们倒着做就ok了,复杂度O(nlogn)

#include <map>#include <set>#include <cmath>#include <ctime>#include <stack>#include <queue>#include <cstdio>#include <cctype>#include <bitset>#include <string>#include <vector>#include <cstring>#include <iostream>#include <algorithm>#include <functional>#define fuck(x) cout<<"["<<x<<"]";#define FIN freopen("input.txt","r",stdin);#define FOUT freopen("output.txt","w+",stdout);//#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long LL;typedef pair<int, int> PII;const int MX = 1e5 + 5;LL F[MX];LL f(LL n) {    return n * (n - 1) * (n - 2) / 6;}int main() {    //FIN;    int T, n, m;    scanf("%d", &T);    while(T--) {        scanf("%d%d", &n, &m);        memset(F, 0, sizeof(F));        for(int i = m; i <= n; i += m) {            F[i] = f(n / i);        }        for(int i = n; i >= m; i--) {            if(F[i]) {                for(int j = i * 2; j <= n; j += i) {                    F[i] -= F[j];                }            }        }        printf("%lld\n", F[m]);    }    return 0;}


0 0
原创粉丝点击