数论分块

对于常数n,使得式子ni=nj\lfloor \frac{n}{i}\rfloor=\lfloor \frac{n}{j}\rfloor成立的最大的i<j<n的j值为nni\lfloor \frac{n}{\lfloor \frac{n}{i}\rfloor}\rfloor,即值ni\lfloor \frac{n}{i}\rfloor所在块的右端点为nni\lfloor \frac{n}{\lfloor \frac{n}{i}\rfloor}\rfloor

例题:T组数据,每组一个整数 。对于每组数据,输出i=1nni\sum_{i=1}^{n}\lfloor \frac{n}{i}\rfloor

long long H(int n) {
  long long res = 0;  // 储存结果
  int l = 1, r;       // 块左端点与右端点
  while (l <= n) {
    r = n / (n / l);  // 计算当前块的右端点
    res += (r - l + 1) * 1LL *(n / l);  // 累加这一块的贡献到结果中。乘上 1LL 防止溢出
    l = r + 1;  // 左端点移到下一块
  }
  return res;
}

有时候需要用到特殊的转化

a%b=ababa\%b=a-b*\lfloor\frac{a}{b}\rfloor

Last updated