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

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



我的标签:做个有情怀的程序员。

你可能感兴趣的:(莫比乌斯反演)