HDU6134 Battlestation Operational

题目链接

题意

​ 求解

f(n)=i=1nj=1nij[(i,j)=1]

其中

[(i,j)=1]={1,gcd(i,j)=10,others

分析

​ =-=又一道公式推论神题。。解法和题解不同,是从网上找的结论,推论过程自行搜索吧。对于向下取整存在公式

g(n)=i=1nj=1nij[(i,j)=1]

g(n)=i|nmu[ni](j=1id[j])

其中 mu[i] 为莫比乌斯函数, d[j] 表示数 j 约数的个数。

于是可以利用筛法求出 d[j] ,再求一次前缀和。然后再次用筛法求出 g[n] 。剩下的问题就是如何将 g[n] 转换为 f[n] 。容易发现,除了 j=1 的时候,其它必然都无法整除,即贡献为1。于是利用欧拉定理求出 <j 且和 j 互质数的个数即可获得 f[n]

代码

#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define MAXN 1001000
const int mod=1e9+7;
int mu[MAXN];
LL ans[MAXN];
LL d[MAXN];
int phi[MAXN];
void getPhi(){
    for(int i=1;ifor(int i=2;iif(phi[i]==i)
            for(int j=i;j1);
}
void getMu(){
    for(int i=1;iint target=i == 1?1:0;
        int delta=target-mu[i];
        mu[i]=delta;
        for(int j=i+i;jvoid init(){
    getPhi();
    getMu();
    for(int i=1;ifor(int j=i;jfor(int i=1;i1])%mod;
    for(int i=1;ifor(int j=i;jfor(int i=1;i1)%mod;
    for(int i=2;i1])%mod;
}
int main(){
    init();
    int n;
    while(~scanf("%d",&n)){
        printf("%d\n",ans[n]);
    }
}

你可能感兴趣的:(莫比乌斯函数,欧拉定理,筛法,多校赛)