HDU 6428 Problem C. Calculate(积性函数)

Problem C. Calculate

ϕ = ϕ ∗ ϵ = ϕ ∗ μ ∗ I ϕ ( n ) = ∑ d ∣ n ( ϕ ∗ μ ) ( d ) 设 g ( n ) = ∑ d ∣ n ( ϕ ∗ μ ) ( d ) ∑ i = 1 A ∑ j = 1 B ∑ k = 1 C ϕ ( g c d ( i , j 2 , k 3 ) ) ∑ i = 1 A ∑ j = 1 B ∑ k = 1 C ∑ d ∣ i , d ∣ j 2 , d ∣ k 3 ( ϕ ∗ μ ) ( d ) ∑ d = 1 A ( ϕ ∗ μ ) ( d ) ∑ i = 1 A ∑ j = 1 B ∑ k = 1 C [ d ∣ i , d ∣ j 2 , d ∣ k 3 ] \phi = \phi * \epsilon = \phi * \mu * I\\ \phi(n) = \sum_{d \mid n} (\phi*\mu)(d)\\ 设g(n) = \sum_{d \mid n}(\phi * \mu)(d)\\ \sum_{i = 1} ^{A} \sum_{j = 1} ^{B} \sum_{k = 1} ^{C} \phi(gcd(i, j ^ 2, k ^ 3))\\ \sum_{i = 1} ^{A} \sum_{j = 1} ^{B} \sum_{k = 1} ^{C} \sum_{d \mid i, d \mid j ^ 2, d \mid k ^ 3} (\phi *\mu)(d)\\ \sum_{d = 1} ^{A} (\phi *\mu)(d) \sum_{i = 1} ^{A} \sum_{j = 1} ^{B} \sum_{k = 1} ^{C}[d \mid i, d \mid j ^ 2, d \mid k ^ 3]\\ ϕ=ϕϵ=ϕμIϕ(n)=dn(ϕμ)(d)g(n)=dn(ϕμ)(d)i=1Aj=1Bk=1Cϕ(gcd(i,j2,k3))i=1Aj=1Bk=1Cdi,dj2,dk3(ϕμ)(d)d=1A(ϕμ)(d)i=1Aj=1Bk=1C[di,dj2,dk3]
x = ∏ p i k i x = \prod p_i ^{k_i} x=piki,唯一分解,如果 x ∣ y t x \mid y ^ t xyt,则有 ∏ p i ⌈ k i t ⌉ ∣ y \prod p_i ^{\lceil \frac{k_i}{t} \rceil} \mid y pitkiy,设 f t ( n ) = ∏ p j k j t f_t(n) = \prod p_j ^ \frac{k_j}{t} ft(n)=pjtkj

上式可得:
∑ d = 1 A ( ϕ ∗ μ ) ( d ) ⌊ d f 1 ( d ) ⌋ ⌊ d f 2 ( d ) ⌋ ⌊ d f 3 ( d ) ⌋ \sum_{d = 1} ^{A}(\phi * \mu)(d) \lfloor \frac{d}{f_1(d)} \rfloor \lfloor \frac{d}{f_2(d)} \rfloor \lfloor \frac{d}{f_3(d)} \rfloor d=1A(ϕμ)(d)f1(d)df2(d)df3(d)d

对于 h = ( ϕ ∗ μ ) ( d ) , f 1 , f 2 , f 3 h = (\phi * \mu)(d), f_1, f_2, f_3 h=(ϕμ)(d),f1,f2,f3都具有积性,所以可以线性筛预处理,最后 O ( A ) O(A) O(A)统计答案。

#include <bits/stdc++.h>

using namespace std;

typedef unsigned uint;

const int N = 1e7 + 10;

uint prime[N], h[N], f1[N], f2[N], f3[N], num[N], primes[N], cnt;

bool st[N];

void init() {
  h[1] = f1[1] = f2[1] = f3[1] = primes[1] = 1;
  for (int i = 2; i < N; i++) {
    if (!st[i]) {
      prime[++cnt] = i;
      h[i] = i - 2;
      f1[i] = i;
      f2[i] = i;
      f3[i] = i;
      primes[i] = i;
      num[i] = 1;
    }
    for (int j = 1; j <= cnt && 1ll * i * prime[j] < N; j++) {
      st[i * prime[j]] = 1;
      if (i % prime[j] == 0) {
        primes[i * prime[j]] = primes[i] * prime[j];
        num[i * prime[j]] = num[i] + 1;
        f1[i * prime[j]] = f1[i] * prime[j];
        f2[i * prime[j]] = f2[i / prime[j]] * prime[j];
        if (i / prime[j] % prime[j] == 0) {
          f3[i * prime[j]] = f3[i / prime[j] / prime[j]] * prime[j];
        }
        else {
          f3[i * prime[j]] = f3[i];
        }
        if(i * prime[j] == primes[i * prime[j]]) {
          h[i * prime[j]] = i * prime[j] - 2 * i + i / prime[j];
        }
        else {
          h[i * prime[j]] = h[i / primes[i]] * h[primes[i * prime[j]]];
        }
        break;
      }
      h[i * prime[j]] = h[i] * h[prime[j]];
      f1[i * prime[j]] = f1[i] * f1[prime[j]];
      f2[i * prime[j]] = f2[i] * f2[prime[j]];
      f3[i * prime[j]] = f3[i] * f3[prime[j]];
      primes[i * prime[j]] = prime[j];
      num[i * prime[j]] = 1;
    }
  }
}

int main() {
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  init();
  int T;
  scanf("%d", &T);
  while (T--) {
    uint A, B, C, ans = 0;
    scanf("%u %u %u", &A, &B, &C);
    for (int d = 1; d <= (int)A; d++) {
      ans += h[d] * (A / f1[d]) * (B / f2[d]) * (C / f3[d]);
    }
    printf("%u\n", ans & ((1 << 30) - 1));
  }
  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值