bzoj3560DZY Loves Math V 欧拉函数

Posted GXZlegend

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3560DZY Loves Math V 欧拉函数相关的知识,希望对你有一定的参考价值。

题目描述

给定n个正整数a1,a2,…,an,求

技术分享图片

的值(答案模10^9+7)。

输入

第一行一个正整数n。
接下来n行,每行一个正整数,分别为a1,a2,…,an。

输出

仅一行答案。

样例输入

3
6
10
15

样例输出

1595


题解

欧拉函数

由于 $\varphi$ 是积性函数,所以可以单独考虑每个质因子的贡献。

那么对于最终的 $a=i_1i_2\dots i_n$ ,若其包含 $p^c\ ,\ c>0$ ,则贡献为 $\frac{p-1}{p}·p^c$ 。因此求出 $p^c$ 的总和,再乘上 $\frac{p-1}{p}$ ,再加上1(都不包含 $p$ 的情况)即可得到 $p$ 的总贡献。

设 $a_j$ 中包含 $p^{c_j}$ ,那么 $p^c$ 的总和就是所有与 $p$ 相关的 $\prod\limits_{j=1}^n\sum\limits_{k=0}^{c_j}p^k$ 减去不含 $p$ 的 $1$ 。

因此最终答案就是 $\prod\limits_{prime(p)}(\frac{p-1}{p}(\prod\limits_{j=1}^n\sum\limits_{k=0}^{c_{p,j}}p^k-1)+1)$ 。

线性筛预处理每个数最小的质因子,对每个数 $O(\log a)$ 分解质因数,复杂度 $O(a+n\log a)$

#include <cstdio>
#define M 10000010
#define mod 1000000007
typedef long long ll;
int pre[M] , prime[M] , tot , val[50] , cnt[50] , top;
ll res[M];
bool np[M];
ll pow(ll x , int y)
{
    ll ans = 1;
    while(y)
    {
        if(y & 1) ans = ans * x % mod;
        x = x * x % mod , y >>= 1;
    }
    return ans;
}
void init()
{
    int n = 10000000 , i , j;
    for(i = 1 ; i <= n ; i ++ ) res[i] = 1;
    for(i = 2 ; i <= n ; i ++ )
    {
        if(!np[i]) pre[i] = prime[++tot] = i;
        for(j = 1 ; j <= tot && i * prime[j] <= n ; j ++ )
        {
            np[i * prime[j]] = 1 , pre[i * prime[j]] = prime[j];
            if(i % prime[j] == 0) break;
        }
    }
}
int main()
{
    init();
    int n , i , x , now , sum;
    ll ans = 1;
    scanf("%d" , &n);
    while(n -- )
    {
        scanf("%d" , &x);
        top = 0;
        for(i = x ; i != 1 ; i /= pre[i])
        {
            if(pre[i] != val[top]) val[++top] = pre[i];
            cnt[top] ++ ;
        }
        for(i = 1 ; i <= top ; i ++ )
        {
            now = sum = 1;
            while(cnt[i]) cnt[i] -- , now *= val[i] , sum += now;
            res[val[i]] = res[val[i]] * sum % mod;
        }
    }
    for(i = 2 ; i <= 10000000 ; i ++ )
        if(!np[i] && res[i] != 1)
            ans = ans * ((res[i] - 1 + mod) * pow(i , mod - 2) % mod * (i - 1) % mod + 1) % mod;
    printf("%lld\n" , ans);
    return 0;
}

 

 

以上是关于bzoj3560DZY Loves Math V 欧拉函数的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj3560] DZY Loves Math V

bzoj3560DZY Loves Math V 欧拉函数

bzoj 3560 DZY Loves Math V - 线性筛 - 数论 - 扩展欧几里得算法

bzoj3309DZY Loves Math

BZOJ3309: DZY Loves Math

bzoj3561DZY Loves Math VI