[BZOJ 5455] [SPOJ 20173] DIVCNT2

本文深入探讨了质因数与约数计数之间的数学关系,通过解析σ0(i)的性质,揭示了如何高效计算特定形式的约数个数。利用μ^2(i)和σ0(j)的乘积,结合杜教筛法,实现了在N^(2/3)的时间复杂度内求解大规模数据问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

洛谷传送门
SPOJ传送门
BZOJ传送门

注: B Z O J BZOJ BZOJ数据范围稍有不同, 博主程序以 B Z O J BZOJ BZOJ为标准实际上是在SPOJ上面卡不过QAQ

Description

img

Input

第一行一个自然数 T T T 表示数据组数

下接 T T T 行,每行一个正整数 n n n

T ≤ 10 , n ≤ 1 0 9 T ≤ 10, n ≤ 10^9 T10,n109

Output

输出 T T T 行,每行一个数字表示答案

Sample Input

4
233333
2333333
23333333
233333333

Sample Output

14145459
191698371
2494643347
31475021381

解题分析

上次在这道题中我们分析出了一个 σ 0 ( i ) \sigma_0(i) σ0(i)的性质, 这里还需要用到一个:
σ 0 ( n 2 ) = ∑ i ∣ n 2 ω ( i ) \sigma_0(n^2)=\sum_{i|n}2^{\omega(i)} σ0(n2)=in2ω(i)
其中 ω ( n ) \omega(n) ω(n)表示 n n n的不同质因数的个数。

仍然考虑将 n n n分解为 n = p 1 a 1 ∗ p 2 a 2 ∗ p 3 a 3 ∗ . . . . . . ∗ p k a k n=p_1^{a_1}*p_2^{a_2}*p_3^{a_3}*......*p_k^{a_k} n=p1a1p2a2p3a3......pkak, 那么对于每个原有的约数 m m m, 那么我们可以让任何一个质数次幂 + a i +a_i +ai得到一个新的组合, 而这样枚举恰好是覆盖了所有情况的。

注意到 2 ω ( n ) 2^{\omega(n)} 2ω(n)还有一个意义: n n n的不含平方因子的约数个数。

因此实际上 2 w ( n ) = ∑ d ∣ n μ 2 ( d ) 2^{w(n)}=\sum_{d|n}\mu^2(d) 2w(n)=dnμ2(d)

所以我们可以设 f ( x ) = σ 0 ( x 2 ) f(x)=\sigma_0(x^2) f(x)=σ0(x2) g ( x ) = 2 ω ( x ) g(x)=2^{\omega(x)} g(x)=2ω(x) h ( x ) = μ 2 ( x ) h(x)=\mu^2(x) h(x)=μ2(x), 那么有
f ( x ) = g ( x ) ∗ I ( x ) g ( x ) = h ( x ) ∗ I ( x ) f ( x ) = h ( x ) ∗ I ( x ) ∗ I ( x ) = h ( x ) ∗ ( I ( x ) ∗ I ( x ) ) = h ( x ) ∗ σ 0 ( x ) f(x)=g(x)*I(x) \\ g(x)=h(x)*I(x) \\ f(x)=h(x)*I(x)*I(x) \\ =h(x)*(I(x)*I(x)) \\ =h(x)*\sigma_0(x) f(x)=g(x)I(x)g(x)=h(x)I(x)f(x)=h(x)I(x)I(x)=h(x)(I(x)I(x))=h(x)σ0(x)
所以就有
∑ i = 1 n f ( x ) = ∑ i = 1 n μ 2 ( i ) ∑ j = 1 ⌊ n i ⌋ σ 0 ( j ) \sum_{i=1}^nf(x) \\ =\sum_{i=1}^n\mu^2(i)\sum_{j=1}^{\lfloor\frac{n}{i}\rfloor}\sigma_0(j) i=1nf(x)=i=1nμ2(i)j=1inσ0(j)
而这两个函数也可以在 N \sqrt N N 的时间内筛出来:
∑ i = 1 n μ 2 ( i ) = ∑ i = 1 n μ ( i ) ⌊ n i 2 ⌋ ∑ i = 1 n σ 0 ( i ) = ∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^n\mu^2(i)=\sum_{i=1}^{\sqrt n}\mu(i)\lfloor\frac{n}{i^2}\rfloor \\ \sum_{i=1}^n\sigma_0(i)=\sum_{i=1}^{n}\lfloor\frac{n}{i}\rfloor i=1nμ2(i)=i=1n μ(i)i2ni=1nσ0(i)=i=1nin

然后可以类似杜教筛, 处理出前 N 2 3 N^\frac{2}{3} N32项, 使得总复杂度在下底分块后达到 O ( N 2 3 ) O(N^\frac{2}{3}) O(N32)

代码如下:

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <bitset>
#include <cstdlib>
#include <tr1/unordered_map>
#include <map>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 1000050
#define ll long long
template <class T>
IN void in(T &x)
{
    x = 0; R char c = gc;
    for (; !isdigit(c); c = gc);
    for (;  isdigit(c); c = gc)
    x = (x << 1) + (x << 3) + c - 48;
}
int pcnt;
short miu[MX], cnt[MX];
int sgm0[MX], sum1[MX], pri[MX / 10], sum2[MX];
bool npr[MX];
std::tr1::unordered_map <ll, ll> mp1, mp2;
IN void get()
{
    miu[1] = sgm0[1] = 1;
    R int i, j, tar;
    for (i = 2; i <= 1e6; ++i)
    {
        if (!npr[i]) miu[i] = -1, sgm0[i] = 2, pri[++pcnt] = i, cnt[i] = 1;
        for (j = 1; j <= pcnt; ++j)
        {
            tar = i * pri[j];
            if (tar > 1e6) break;
            npr[tar] = true;
            if (!(i % pri[j]))
            {
                miu[tar] = 0;
                sgm0[tar] = sgm0[i] / (cnt[i] + 1) * (cnt[i] + 2);
                cnt[tar] = cnt[i] + 1;
                break;
            }
            miu[tar] = -miu[i];
            sgm0[tar] = sgm0[i] << 1;
            cnt[tar] = 1;
        }
    }
    for (R int i = 1; i <= 1e6; ++i)
    {
        sum1[i] = sum1[i - 1] + (miu[i] != 0);
        sum2[i] = sum2[i - 1] + sgm0[i];
    }
}
IN ll solve1(R ll pos)//for sigma mu(i)^2
{
    if (pos <= 1e6) return sum1[pos];
    if (mp1.count(pos)) return mp1[pos];
    ll bd = std::sqrt(pos);
    ll ret = 0;
    for (R ll i = 1; i <= bd; ++i) ret += miu[i] * (pos / (i * i));
    return mp1[pos] = ret;
}
IN ll solve2(R ll pos)//for sigma sig0(i)
{
    if (pos <= 1e6) return sum2[pos];
    if (mp2.count(pos)) return mp2[pos];
    ll ret = 0;
    for (R ll lef = 1, rig; lef <= pos; lef = rig + 1)
    {
        rig = pos / (pos / lef);
        ret += (pos / lef) * (rig - lef + 1);
    }
    return mp2[pos] = ret;
}
int main(void)
{
    int T;
    ll n, ans;
    in(T); get();
    W (T--)
    {
        in(n); ans = 0;
        for (ll lef = 1, rig; lef <= n; lef = rig + 1)
        {
            rig = n / (n / lef);
            ans += (solve1(rig) - solve1(lef - 1)) * solve2(n / lef);
        }
        printf("%lld\n", ans);
    }
}
资源下载链接为: https://pan.quark.cn/s/9648a1f24758 这个HTML文件是一个专门设计的网页,适合在告白或纪念日这样的特殊时刻送给女朋友,给她带来惊喜。它通过HTML技术,将普通文字转化为富有情感和创意的表达方式,让数字媒体也能传递深情。HTML(HyperText Markup Language)是构建网页的基础语言,通过标签描述网页结构和内容,让浏览器正确展示页面。在这个特效网页中,开发者可能使用了HTML5的新特性,比如音频、视频、Canvas画布或WebGL图形,来提升视觉效果和交互体验。 原本这个文件可能是基于ASP.NET技术构建的,其扩展名是“.aspx”。ASP.NET是微软开发的一个服务器端Web应用程序框架,支持多种编程语言(如C#或VB.NET)来编写动态网页。但为了在本地直接运行,不依赖服务器,开发者将其转换为纯静态的HTML格式,只需浏览器即可打开查看。 在使用这个HTML特效页时,建议使用Internet Explorer(IE)浏览器,因为一些老的或特定的网页特效可能只在IE上表现正常,尤其是那些依赖ActiveX控件或IE特有功能的页面。不过,由于IE逐渐被淘汰,现代网页可能不再对其进行优化,因此在其他现代浏览器上运行可能会出现问题。 压缩包内的文件“yangyisen0713-7561403-biaobai(html版本)_1598430618”是经过压缩的HTML文件,可能包含图片、CSS样式表和JavaScript脚本等资源。用户需要先解压,然后在浏览器中打开HTML文件,就能看到预设的告白或纪念日特效。 这个项目展示了HTML作为动态和互动内容载体的强大能力,也提醒我们,尽管技术在进步,但有时复古的方式(如使用IE浏览器)仍能唤起怀旧之情。在准备类似的个性化礼物时,掌握基本的HTML和网页制作技巧非常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值