bzoj4176 Lucas的数论 (杜教筛 +莫比乌斯反演)
来源:互联网 发布:java 队列 线程安全 编辑:程序博客网 时间:2024/06/01 08:51
bzoj4176 Lucas的数论
原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=4176
题意:
去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了。
在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i的约数个数。他现在长大了,题目也变难了。
求如下表达式的值:
其中 表示ij的约数个数。
他发现答案有点大,只需要输出模1000000007的值。
数据范围
n <= 10^9
题解:
由
原式
观察到后面两个式子的形式几乎完全一样,
用i替换x/t,得:
定义,
那么,
前面对于
定义梅滕斯函数
M(n)=∑ni=1μ(i) ,使用[n=1]=∑d|nμ(d)
1=∑i=1n[i=1]=∑i=1n∑d|iμ(d)=∑i=1n∑d=1⌊ni⌋μ(d)=∑i=1nM(⌊ni⌋)
因此M(n)=1−∑ni=2M(⌊ni⌋) ,问题可在O(n23) 时间复杂度下解决。
——摘自浅谈一类积性函数的前缀和
预处理
因为我们最后for的时候是按(n/i)分块一段一段地for,所以访问到的mu前缀和只会是
所以要预先处理n/i>S的
因为 n/i>S,所以i<=S,所以数组下标是按i保存。
对于后面
据PoPoQQQ大佬的博客,时间复杂度是
于是总复杂度
代码:
#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<algorithm>#define LL long longusing namespace std;const int mod=1000000007;const int N=10000007;int n,S,mu[N],sum[N],p[N],ptot=0;bool is[N];void shai(){ memset(is,0,sizeof(is)); is[1]=1; mu[1]=1; for(int i=2;i<=S;i++) { if(!is[i]) {p[++ptot]=i;mu[i]=-1;} for(int j=1;j<=ptot;j++) { int pp=p[j]; if(1LL*pp*i>=1LL*N) break; int x=pp*i; is[x]=1; mu[x]=mu[i]*mu[pp]; if(i%pp==0) {mu[x]=0; break;} } } mu[0]=0; for(int i=1;i<=S;i++) mu[i]=(mu[i-1]+mu[i]+mod)%mod;}int cal(int x){ int ans=0; for(int i=1,ed;i<=x;i=ed+1) { ed=(x/(x/i)); ans=(ans+(1LL*(ed-i+1)*(x/i))%mod)%mod; } return ans;}int getmu(int x){ if(x<=S) return mu[x]; else return sum[n/x];}void init(){ shai(); int top=1; while(n/top>S) top++; for(int j=top;j>=1;j--) { int now=n/j; sum[j]=1; for(int i=2,ed;i<=now;i=ed+1) { ed=now/(now/i); sum[j]=(sum[j]-(1LL*(ed-i+1)*getmu(now/i))%mod+mod)%mod; } } }int main(){ scanf("%d",&n); S=ceil(pow((double)n,0.75)); init(); int ans=0; for(int i=1,ed;i<=n;i=ed+1) { ed=n/(n/i); int tmp=cal((n/i)); int ret=(getmu(ed)-getmu(i-1)+mod)%mod; ret=(1LL*ret*tmp)%mod; ret=(1LL*ret*tmp)%mod; ans=(ans+ret)%mod; } printf("%d\n",ans); return 0;}
补充:
1、
证明如下:
n,m的任意约数都可表示为
即
上式即是枚举
为什么必须
若
会算重。
2、
- bzoj4176 Lucas的数论 (杜教筛 +莫比乌斯反演)
- [杜教筛] BZOJ4176. Lucas的数论
- BZOJ 4176 Lucas的数论 莫比乌斯反演
- bzoj 4176 Lucas的数论 莫比乌斯反演
- bzoj4176 Lucas 的数论
- [bzoj4176]Lucas的数论
- BZOJ 4176: Lucas的数论 莫比乌斯反演 杜教筛
- 【数论】(莫比乌斯反演)关于莫比乌斯反演的小结
- 数论 莫比乌斯反演
- bzoj 4176: Lucas的数论 (反演)
- BZOJ_P2820 YY的GCD(数论+莫比乌斯反演)
- 【BZOJ3601】一个人的数论,莫比乌斯反演+高斯消元
- bzoj3601 一个人的数论 莫比乌斯反演+高斯消元
- 莫比乌斯反演公式(数论)
- 一些有用的数论知识。(莫比乌斯反演)
- 数学(论)里的一些定理(莫比乌斯反演,傅立叶变换,数论变换...)
- 【codevs4355】王的对决(简单数论) 莫比乌斯反演
- 【BZOJ2154】Crash的数字表格,数论练习之二维LCM(莫比乌斯反演)
- Minimum Path Sum
- CentOS系统下的Hadoop集群(第4期)_SecureCRT使用
- SpringCloud教程八:消息总线(SpringCloud Bus)
- Ajax学习心得
- 外观模式Facade(结构型)
- bzoj4176 Lucas的数论 (杜教筛 +莫比乌斯反演)
- 文章标题
- VS2015+MATLAB2016b混合编程
- CentOS系统下的Hadoop集群(第3期)_VSFTP安装配置
- jdk配tomcat与oracle
- 【ACM/ICPC训练】修理牧场
- 预编译
- JavaScript高级程序设计(第3版)笔记(五)
- 梯度下降 — Gradient Descent