bzoj 4176: Lucas的数论 -- 杜教筛,莫比乌斯反演
2017-11-22 17:43
295 查看
4176: Lucas的数论
Time Limit: 30 Sec Memory Limit: 256 MBDescription
去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了。在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i的约数个数。他现在长大了,题目也变难了。
求如下表达式的值:
其中 表示ij的约数个数。
他发现答案有点大,只需要输出模1000000007的值。
Input
第一行一个整数n。Output
一行一个整数ans,表示答案模1000000007的值。Sample Input
2Sample Output
8HINT
对于100%的数据n <= 10^9。Source
emmmm,转载一份题解吧,写的很清晰了 http://blog.csdn.net/clove_unique/article/details/67633389我们先反演一下,化简成这样
然后就括号内的东西可以O(√n)算出,然后杜教筛出mu值,就可以了
(复杂度不要问我qwq
#include<map> #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define mod 1000000007 #define ll long long #define N 1000555 int mu ,pri ,tot; bool vs ; void INIT() { mu[1]=1; for(int i=2;i<N;i++) { if(!vs[i]) pri[++tot]=i,mu[i]=-1; for(int j=1;j<=tot&&pri[j]*i<N;j++) { vs[pri[j]*i]=1; if(i%pri[j]==0){mu[pri[j]*i]=0;break;} mu[pri[j]*i]=-mu[i]; } mu[i]+=mu[i-1]; } } int n; ll ans; ll F(int x) { ll tp=0; for(int i=1,j;i<=x;i=j+1) { j=x/(x/i); (tp+=(ll)(x/i)*(j-i+1))%=mod; } return tp*tp%mod; } map<int,int>p; ll sol(int x) { if(x<N) return mu[x]; if(p[x]) return p[x]; ll ta=1; for(int i=2,j;i<=x;i=j+1) { j=x/(x/i); (ta-=sol(x/i)*(j-i+1))%=mod; } if(ta<0) ta+=mod; return p[x]=ta; } int main() { INIT(); scanf("%d",&n); for(int i=1,j;i<=n;i=j+1) { j=n/(n/i); (ans+=F(n/i)*(sol(j)-sol(i-1)+mod))%=mod; } printf("%lld\n",ans); return 0; }
相关文章推荐
- 【bzoj 4176】 Lucas的数论 莫比乌斯反演(杜教筛)
- bzoj4176 Lucas的数论 (杜教筛 +莫比乌斯反演)
- bzoj 4176: Lucas的数论 莫比乌斯反演+杜教筛
- [杜教筛] BZOJ4176. Lucas的数论
- BZOJ 4176: Lucas的数论 [杜教筛]
- 【BZOJ 4176】 Lucas的数论 - 杜教筛
- [杜教筛 约数个数前缀和] BZOJ 4176 Lucas的数论
- BZOJ4176 Lucas的数论 【莫比乌斯反演 + 杜教筛】
- [BZOJ4176]Lucas的数论(莫比乌斯反演+杜教筛)
- BZOJ 4176 Lucas的数论
- BZOJ 4176 Lucas的数论 莫比乌斯反演
- bzoj 4176: Lucas的数论 (反演)
- BZOJ 4176: Lucas的数论 莫比乌斯反演 杜教筛
- bzoj 4176 Lucas的数论
- BZOJ4176 Lucas的数论
- 【BZOJ4176】Lucas的数论 莫比乌斯反演
- BZOJ4176: Lucas的数论
- 【bzoj4176】Lucas的数论 莫比乌斯反演+杜教筛
- BZOJ_4176_Lucas的数论_杜教筛+莫比乌斯反演
- ●BZOJ 4176 Lucas的数论