码迷,mamicode.com
首页 > 其他好文 > 详细

机房测试3:太阳神 ra (莫比乌斯反演)

时间:2019-10-04 22:53:58      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:++   pre   a*   gif   register   style   stdin   scanf   题目   

题目:

技术图片

 

技术图片

 

分析:
(终于在yyr大佬的援助下弄懂了这道题。。。)

首先lcm>n的限制太少,不好直接处理,转换成求补集,也就是lcm<=n,最后用n^n-ans即可。

考虑怎么求lcm<=n:

技术图片

 

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100005
#define ri register int
const ll mod=1e9+7;
int mu[N],lim,pri[N],su[N],cnt=0;
void init()
{
    mu[1]=1;
    for(ri i=2;i<=lim;++i){
        if(!pri[i]) mu[i]=-1,su[++cnt]=i;
        for(ri j=1;j<=cnt&&i*su[j]<=lim;++j){
            pri[i*su[j]]=1;
            if(i%su[j]==0) { mu[i*su[j]]=0; break; }
            else mu[i*su[j]]=-mu[i];
        }
    }
}
int main()
{
    freopen("ra.in","r",stdin);
    freopen("ra.out","w",stdout);
    ll n;    
    scanf("%lld",&n);
    lim=(int)(sqrt(n)+0.5);
    init();
    ll anss=0;
    for(ri d=1;d<=lim;++d){
        ll tmp=n/d/d,ans=0;
        for(ll a=1;a*a*a<=tmp;++a)//在极小的范围里面枚举a和b 就可以得到c的范围 
         for(ll b=a;b*b<=tmp/a;++b){
             ll c=tmp/a/b-b;//注意c是统计的范围 
             if(a==b) ans=( ans + 1 + c*3 ) %mod;
             else ans=( ans + 3 + c*6 ) %mod;
        }
        anss=( anss + mu[d]*ans )%mod;
    }
    n%=mod;
    printf("%lld\n",(n*n%mod-anss+mod)%mod);
}
View Code

 

 

 

 

 

 

 

 

 

 

 

机房测试3:太阳神 ra (莫比乌斯反演)

标签:++   pre   a*   gif   register   style   stdin   scanf   题目   

原文地址:https://www.cnblogs.com/mowanying/p/11623314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!