zoukankan      html  css  js  c++  java
  • scau 18087 开始我是拒接的 mobius

    其实有一个很有用的技巧就是,把gcd = 4的贡献,压去gcd = 2时的贡献,就不需要考虑这么多的了。

    为什么可以把gcd = 4的,压去gcd = 2的呢,gcd = 12的,压去gcd = 6的去算呢,

    其实这就是mobius的容斥原理,mu[4] = 0,mu[12] = 0,

    例如:

    http://www.cnblogs.com/liuweimingcprogram/p/6818754.html

    这题的思路是,把每个数字都质因数分解,比如分解成12 = 2 * 3

    然后暴力枚举每个质因子选or不选,就能知道,12的所有因子,

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    const int maxn = 100000 + 20;
    int prime[maxn][12];
    void initPrime() {
        int mx = 0;
        for (int i = 2; i <= maxn - 20; ++i) {
            if (prime[i][0]) continue;
            for (int j = i; j <= maxn - 20; j += i) {
                prime[j][++prime[j][0]] = i;
    //            mx = max(mx, prime[j][0]);
            }
        }
    }
    int num[maxn];
    void init(int val) {
        int en = (1 << prime[val][0]) - 1;
        for (int i = 1; i <= en; ++i) {
            int t = 1;
            for (int j = 1; j <= prime[val][0]; ++j) {
                if (i & (1 << (j - 1))) {
                    t *= prime[val][j];
                }
            }
            num[t]++;
        }
    }
    int calc(int val) {
        int ans = 0;
        int en = (1 << prime[val][0]) - 1;
        for (int i = 1; i <= en; ++i) {
            int t = 1;
            int cnt = 0;
            for (int j = 1; j <= prime[val][0]; ++j) {
                if (i & (1 << (j - 1))) {
                    t *= prime[val][j];
                    cnt++;
                }
            }
            if (cnt & 1) ans += num[t];
            else ans -= num[t];
        }
        return ans;
    }
    void work() {
    //    int out = 3 * 5 * 7;
    //    for (int i = 1; i <= prime[out][0]; ++i) {
    //        printf("%d ", prime[out][i]);
    //    }
        int n, q;
        scanf("%d%d", &n, &q);
        for (int i = 1; i <= n; ++i) {
            int val;
            scanf("%d", &val);
            init(val);
        }
        for (int i = 1; i <= q; ++i) {
            int val;
            scanf("%d", &val);
            printf("%d
    ", n - calc(val));
        }
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        initPrime();
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    Eclipse中安装Tomcat
    Merge Query
    如何生成Java Key以及sign一个jar
    Create MSSQL Procedure
    MSSQL Procudure Sample
    MSSQL Get Last Monday and Last Sunday
    oracle Data blocks,Extents,Segments
    Oracle Index Clustering Factor(集群因子)
    mapreduce工作原理
    python 实现一个TwoSum的例子
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6919379.html
Copyright © 2011-2022 走看看