[杜教筛 反演] LOJ#6229. 这是一道简单的数学题
2018-01-18 20:01
260 查看
推一推式子可以得到 ans=∑d=1n∑i=1⌊nd⌋∑j=1iij[gcd(i,j)=1]
有一个经典的等式是 ∑i=1ni[gcd(i,n)=1]=[n=1]+nφ(n)2
所以就有 ans=n2+12∑d=1n∑i=1⌊nd⌋i2φ(i)
考虑 ∑ni=1i2φ(i) 的出现次数,可以得到 ans=n2+12∑i=1ni2φ(i)⌊ni⌋
杜教筛
有一个经典的等式是 ∑i=1ni[gcd(i,n)=1]=[n=1]+nφ(n)2
所以就有 ans=n2+12∑d=1n∑i=1⌊nd⌋i2φ(i)
考虑 ∑ni=1i2φ(i) 的出现次数,可以得到 ans=n2+12∑i=1ni2φ(i)⌊ni⌋
杜教筛
#include <cstdio> #include <iostream> #include <algorithm> #include <map> using namespace std; typedef long long ll; const int N=1000010,P=1e9+7,inv2=P+1>>1,inv6=(P+1)/6; int n,lim,p ,phi ,pre ; inline void Pre(const int n){ phi[1]=1; for(int i=2;i<=n;i++){ if(!p[i]) p[++*p]=i,phi[i]=i-1; for(int j=1;j<=*p && 1LL*p[j]*i<=n;j++){ p[p[j]*i]=1; if(i%p[j]) phi[i*p[j]]=phi[i]*phi[p[j]]; else{ phi[i*p[j]]=phi[i]*p[j]; break; } } } for(int i=1;i<=n;i++) pre[i]=(pre[i-1]+1LL*phi[i]*i%P*i)%P; } map<ll,int> M; inline int calc(ll l,ll r){ l%=P; r%=P; return (r-l+1)*(l+r)%P*inv2%P; } inline int calc(ll n){ n%=P; return n*(n+1)%P*(2*n+1)%P*inv6%P; } inline int calc2(ll l,ll r){ return (calc(r)-calc(l-1))%P; } inline int calc3(ll n){ return 1LL*calc(1,n)*calc(1,n)%P; } inline int S(ll n){ if(n<=lim) return pre ; if(M.count(n)) return M ; int ret=calc3(n); for(ll i=2,j;i<=n;i=j+1){ j=n/(n/i); ret=(ret-1LL*calc2(i,j)*S(n/i))%P; } return M =ret; } int main(){ ll n; cin>>n; Pre(lim=1e6); int ans=0,lst=0; for(ll i=1,j;i<=n;i=j+1){ j=n/(n/i); int cur=S(j); ans=(ans+1LL*(cur-lst)*(n/i))%P; lst=cur; } ans=(ans+n)%P*inv2%P; printf("%d\n",(ans+P)%P); return 0; }
相关文章推荐
- [杜教筛][莫比乌斯反演] LOJ #6229. 这是一道简单的数学题
- bjfu1070 一道简单的数学题
- NBUT 1647 又一道简单题【数学+枚举】
- 偶见一道华为笔试题(简单的题更显算法啊--不可忽视的数学)
- 有一道十分简单的数学题,但是我就是没想出来,不得以发在首页求助
- 有一道十分简单的数学题,但是我就是没想出来,不得以发在首页求助
- numpy 解一道简单数学题
- 一道简单数学题
- 简单一道数学题 剿灭100%垃圾邮件
- POJ1142Smith Numbers一道简单的数学题
- 一道简单数学题
- qduoj 102 一道非常简单的数学题(构造)
- 一道简单数学题!10人有11个人算错!!
- noj一道简单的数学题
- 一道简单的算法问题--数学的魅力
- 洛谷P3768 简单的数学题 【莫比乌斯反演 + 杜教筛】
- 一道简单的面试题
- 数学之美系列五 -- 简单之美:布尔代数和搜索引擎的索引
- ZZULIOJ 1793: 有趣的球(简单数学)
- 一道面试题(Nim取子游戏)——如何将数学思维应用到编程中