hdu 6134 Battlestation Operational (莫比乌斯反演+反演一般做法)

题目链接:哆啦A梦传送门

题意:
f ( n ) = ∑ i = 1 n ∑ j = 1 i ⌈ n i ⌉ [ g c d ( i , j ) = = 1 ] f(n)=\sum_{i=1}^{n}\sum_{j=1}^{i}\lceil \frac{n}{i} \rceil [gcd(i,j)==1] f(n)=i=1nj=1iin[gcd(i,j)==1]

题解:参考博客:神犇
此公式大部分都是参考博客里面的。写这篇只是为了自己以后好复习回顾。

我们先化简一下:

f ( n ) = ∑ i = 1 n ∑ j = 1 i ⌈ n i ⌉ [ g c d ( i , j ) = = 1 ] = ∑ i = 1 n ( ∑ j = 1 i ⌊ n i ⌋ [ g c d ( i , j ) = = 1 ] + ϕ ( n ) − 1 ) 只 有 n 与 i 互 质 时 , 向 上 取 整 才 会 多 1 = ∑ i = 1 n ∑ j = 1 i ( ⌊ n i ⌋ [ g c d ( i , j ) = = 1 ] ) + ∑ i = 1 n ϕ ( n ) − n \begin{aligned} f(n)&=\sum_{i=1}^{n}\sum_{j=1}^{i}\lceil \frac{n}{i} \rceil [gcd(i,j)==1]\\ &=\sum_{i=1}^{n}(\sum_{j=1}^{i}\lfloor \frac{n}{i} \rfloor [gcd(i,j)==1]+\phi(n)-1) 只有n与i互质时,向上取整才会多1\\ &=\sum_{i=1}^{n}\sum_{j=1}^{i}(\lfloor \frac{n}{i} \rfloor [gcd(i,j)==1])+\sum_{i=1}^{n}\phi(n)-n\\ \end{aligned} f(n)=i=1nj=1iin[gcd(i,j)==1]=i=1n(j=1iin[gcd(i,j)==1]+ϕ(n)1)ni1=i=1nj=1i(in[gcd(i,j)==1])+i=1nϕ(n)n

我们再设:
首先我们要知道莫比乌斯函数有这样一个性质: ∑ d ∣ n u ( d ) = [ n = = 1 ] \sum_{d|n}u(d) =[n==1] dnu(d)=[n==1]
g ( n ) = ∑ i = 1 n ∑ j = 1 i ( ⌊ n i ⌋ [ g c d ( i , j ) = = 1 ] ) = ∑ i = 1 n ∑ j = 1 i ( ⌊ n i ⌋ ∑ d ∣ ( i , j ) u ( d ) ) 我 们 现 在 枚 举 d , 设 i = k 1 d , j = k 2 d , 那 么 有 = ∑ d = 1 n u ( d ) ∑ k 1 n / d ∑ k 2 k 1 ⌊ k 1 k 2 ⌋ \begin{aligned}g(n)&=\sum_{i=1}^{n}\sum_{j=1}^{i}(\lfloor \frac{n}{i} \rfloor [gcd(i,j)==1])\\ &=\sum_{i=1}^{n}\sum_{j=1}^{i}(\lfloor \frac{n}{i} \rfloor \sum_{d|(i,j)}u(d))\\ 我们现在枚举d,设i=k_1d,j=k_2d,那么有\\ &=\sum_{d=1}^{n}u(d)\sum_{k_1}^{n/d}\sum_{k_2}^{k_1}\lfloor \frac{k_1}{k_2}\rfloor \\ \end{aligned} g(n)di=k1d,j=k2d,=i=1nj=1i(in[gcd(i,j)==1])=i=1nj=1i(ind(i,j)u(d))=d=1nu(d)k1n/dk2k1k2k1

我们知道: ∑ i = 1 n ⌊ n i ⌋ = ∑ i = 1 n σ ( i ) , σ ( i ) 表 示 i 的 正 因 子 个 数 。 \begin{aligned}\sum_{i=1}^{n}\lfloor \frac{n}{i}\rfloor=\sum_{i=1}^{n} \sigma(i) , \sigma(i)表示i的正因子个数。\end{aligned} i=1nin=i=1nσ(i),σ(i)i
一 个 很 简 单 的 证 明 , 对 于 每 个 i , ⌊ n i ⌋ 表 示 在 [ 1 , n ] 中 有 ⌊ n i ⌋ 个 因 子 i 例 如 : i 等 于 1 , n = 4 , ⌊ 4 1 ⌋ = 4 , 即 在 [ 1 , 4 ] 中 每 个 数 都 存 在 因 子 1 \begin{aligned} 一个很简单的证明,对于每个i,\lfloor \frac{n}{i}\rfloor表示在[1,n]中有\lfloor \frac{n}{i}\rfloor个因子i\\ 例如:i等于1,n=4, \lfloor \frac{4}{1}\rfloor=4,即在[1,4]中每个数都存在因子1\end{aligned} iin[1,n]ini:i1,n=4,14=4,[1,4]1

那么上式就可化简为:
g ( n ) = ∑ d = 1 n u ( d ) ∑ k 1 n / d ∑ k 2 k 1 ⌊ k 1 k 2 ⌋ = ∑ d = 1 n u ( d ) ∑ k 1 n / d ∑ k 2 k 1 σ ( k 2 ) \begin{aligned}g(n)&=\sum_{d=1}^{n}u(d)\sum_{k_1}^{n/d}\sum_{k_2}^{k_1}\lfloor \frac{k_1}{k_2}\rfloor \\ &=\sum_{d=1}^{n}u(d)\sum_{k_1}^{n/d}\sum_{k_2}^{k_1} \sigma(k_2)\\\end{aligned} g(n)=d=1nu(d)k1n/dk2k1k2k1=d=1nu(d)k1n/dk2k1σ(k2)

我们设 h ( n ) = ∑ i n ∑ j i σ ( j ) \begin{aligned}h(n)=\sum_{i}^{n}\sum_{j}^{i} \sigma(j)\end{aligned} h(n)=injiσ(j),这个我们可以先线性筛出来 σ ( n ) \sigma(n) σ(n),接着预处理前缀和就可以求得 h ( n ) h(n) h(n)

那么最终的式子就为:

f ( n ) = ∑ d = 1 n u ( d ) h ( n d ) + ∑ i = 1 n ϕ ( n ) − n \begin{aligned}f(n)=\sum_{d=1}^{n}u(d)h(\frac{n}{d})+\sum_{i=1}^{n}\phi(n)-n\end{aligned} f(n)=d=1nu(d)h(dn)+i=1nϕ(n)n

我们现在总结下:
根据题目给的公式或者自己推的公式:
1,如果有向上取整的先化成向下取整(一般跟欧拉函数挂钩)。
2,看到有某个 [条件变量=1],我们此时要能反应出莫比乌斯反演的一个性质: ∑ d ∣ 条 件 变 量 u ( d ) \sum_{d|条件变量}u(d) du(d) ,接着我们就把d给拿出来枚举,并让其它积分变量满足相应的条件(一般n/d等等)
3,接着我们要熟记一些公式,因为我们可以将它们替换,例如此题的 ∑ i = 1 n ⌊ n i ⌋ = ∑ i = 1 n σ ( i ) , σ ( i ) 表 示 i 的 正 因 子 个 数 。 \begin{aligned}\sum_{i=1}^{n}\lfloor \frac{n}{i}\rfloor=\sum_{i=1}^{n} \sigma(i) , \sigma(i)表示i的正因子个数。\end{aligned} i=1nin=i=1nσ(i),σ(i)i公式。
4,有些化简后的式子不是我们常用的能被替换的公式(此公式很容易求得),那么此时就很可能要想到这是不是积性函数,要是的话,我们就要往这方面去做了,但有时积性函数不好判断,也可以大胆假设它就为积性函数,因为大部分我们遇到的都是积性函数。不过我们还是得到掌握下积性函数的判别方法,比如,我们要积累一些积性函数,多个积性函数相乘也为积性函数。知道是积性函数之后,我们就可以在线性筛那里把它们给筛出来

线性筛分为3部分:
1.n本身是素数,这个根据积性函数的定义可得,很容易求。
2.i%prime[j]!=0,这个也是根据积性函数的性质可得,即f(a)f(b)=f(ab)。
3.i%prime[j]==0,这个可能需要找规律加灵光一闪。

代码:


#include<bits/stdc++.h>

using namespace std;

const int N=1e6+10;

typedef long long LL;

const LL mod=1e9+7;
int prime[N],tot;/// 筛素数 ,从0下标开始存储

int mu[N];///莫比乌斯函数

int phi[N]; ///欧拉函数

///facnum[i]表示i的约数个数,d[i],表示i的最小质因子的次幂
int facnum[N],d[N];

bool vis[N];

///函数h,欧拉函数前缀和,莫比乌斯前缀和
LL h[N],sum_phi[N],sum_mu[N];

void init()
{
    tot = 0;
    phi[1] = 1;
    mu[1] = 1;
    facnum[1] = 1;

    for(int i = 2; i < N; i++)
    {
        if(!vis[i])
        {
            phi[i] = i - 1;
            mu[i] = -1;
            prime[tot++] = i;
            facnum[i] = 2;
            d[i] = 1;
        }
        for(int j = 0; j < tot && i * prime[j] < N; j++)
        {
            vis[i * prime[j]] = true;
            if(i % prime[j] == 0)
            {
                phi[i * prime[j]] = phi[i] * prime[j];
                mu[i * prime[j]] = 0;
                facnum[i * prime[j]] = facnum[i] / (d[i] + 1) * (d[i] + 2);
                d[i * prime[j]] = d[i] + 1;
                break;
            }
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            mu[i * prime[j]] = -mu[i];
            facnum[i * prime[j]] = facnum[i] * 2;
            d[i * prime[j]] = 1;
        }
    }

    sum_phi[0]=0;
    LL item=0;
    for(int i=1;i<N;i++){
        sum_phi[i]=(sum_phi[i-1]+phi[i])%mod;
        sum_mu[i]=sum_mu[i-1]+mu[i];
        
        ///递推求h(i)
        item=(item+facnum[i])%mod;
        h[i]=(h[i-1]+item)%mod;
        
    }

}

int main()
{
    init();

    int n;

    while(~scanf("%d",&n))
    {
        int r;
        LL item=(sum_phi[n]-n+mod)%mod;
        for(int l=1;l<=n;l=r+1){
            r=n/(n/l);
            item=(item+(sum_mu[r]-sum_mu[l-1]+mod)%mod*h[n/l]%mod)%mod;
        }
        printf("%lld\n",item);
    }


    return 0;
}




我的标签:做个有情怀的程序员。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值