zoukankan      html  css  js  c++  java
  • BZOJ 1114 Number theory(莫比乌斯反演+预处理)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=71738

    题意:给你一个整数序列a1, a2, a3, ... , an。求gcd(ai, aj) = 1 且 i < j的对数。

    思路:利用莫比乌斯反演很快就能得到公式,但是求解时我们要知道序列中1, 2, 3, ... , max(a1, a2, ... , an)的倍数各是多少。我们用num[i]=k,来表示序列中有k个数是i的倍数,那么这部分对结果的影响是mu[i]*(k - 1) * k / 2。最后的结果就是sigma(mu[i]*(k - 1) * k / 2)。

    code:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 const int MAXN = 250000;
     7 int num[MAXN];        // num[i]表示 满足(i|ak)的个数 
     8 int tmp[MAXN];        // 标记哪些数有
     9 bool check[MAXN];
    10 int primes[MAXN];
    11 int mu[MAXN];
    12 
    13 void moblus()
    14 {
    15     memset(check, false, sizeof(check));
    16     mu[1] = 1;
    17     int cnt = 0;
    18     for (int i = 2; i < MAXN; ++i) {
    19         if (!check[i]) {
    20             primes[cnt++] = i;
    21             mu[i] = -1;
    22         }
    23         for (int j = 0; j < cnt; ++j) {
    24             if (i * primes[j] > MAXN) break;
    25             check[i * primes[j]] = true;
    26             if (i % primes[j] == 0) {
    27                 mu[i * primes[j]] = 0;
    28                 break;
    29             } else {
    30                 mu[i * primes[j]] = -mu[i];
    31             }
    32         }
    33     }
    34 }
    35 
    36 int main()
    37 {
    38     moblus();
    39     int n;
    40     while (scanf("%d", &n) != EOF) {
    41         memset(num, 0, sizeof(num));
    42         memset(tmp, 0, sizeof(tmp));
    43         int tmax = 0;
    44         for (int i = 0; i < n; ++i) {
    45             int x;
    46             scanf("%d", &x);
    47             ++tmp[x];
    48             tmax = max(tmax, x);
    49         }
    50         for (int i = 1; i <= tmax; ++i) {
    51             for (int j = i; j <= tmax; j += i) {
    52                 num[i] += tmp[j];
    53             }
    54         }
    55         LL ans = 0;
    56         for (int i = 1; i <= tmax; ++i) {
    57             ans += (LL)mu[i] * num[i] * (num[i] - 1) / 2;
    58         }
    59         printf("%lld
    ", ans);
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    记录
    Remote System Upgrade With Cyclone III Devices
    【Diary】Noip2020 游记
    【Diary】CSP-S 2020 游记
    【Diary】JZSC 2020 旅 游 记(迫真
    【题解】Luogu P2671 【求和】
    51nod 1153 选择子序列
    Luogu P4116 Qtree3
    Luogu P4114 Qtree1
    【Contest】Nowcoder 假日团队赛1 题解+赛后总结
  • 原文地址:https://www.cnblogs.com/ykzou/p/4796121.html
Copyright © 2011-2022 走看看