1. 程式人生 > >[BZOJ4176]Lucas的數論(莫比烏斯反演+杜教篩)

[BZOJ4176]Lucas的數論(莫比烏斯反演+杜教篩)

題目描述

傳送門

題解

做約數個數和的時候有一個結論:

d(nm)=i|nj|m[(i,j)=1]
直接套進去
i=1nj=1mx|iy|j[(x,y)=1]
然後根據反演公式[n=1]=d|nμ(d)
=d=1nμ(d)x=1n[d|x]i=1n[x|i]y=1n[d|y]j=1n[y|j]
x=dx,y=dy,再令i=di,j=dj
=d=1nμ(d)(x=1ndi=1nd[x|i])2
=d=1nμ(d)(x=1ndndx)2
f(n)=i=1nni,這個可以在O(n)的時間內算出
那麼原式=d=1nμ(d)f
(nd)

不加求μ時間是O(n34)?不大會算…寫出來跑了跑感覺穩
用杜教篩預處理μ然後就可以做了
首先線篩出來n34μ,然後如果nin34之內就可以直接查詢,但是如果不在範圍內就需要查詢一下了。不過可以發現不在範圍內的數非常有限,找出這些數了之後從小到大求,記錄一個數組sum(d)表示[1...nd]μ的和,這樣就可以做到O(1)查詢了
時間似乎還是O(n34)

程式碼

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map> using namespace std; #define Mod 1000000007 #define LL long long #define N 10000005 int n,k=1000000; int prime[N],p[N],mu[N]; LL ans,sum[N]; void get() { mu[1]=1; for (int i=2;i<=k;++i) { if (!p[i]) { prime[++prime[0]]=i; mu[i]=-1; } for
(int j=1;j<=prime[0]&&i*prime[j]<=k;++j) { p[i*prime[j]]=1; if (i%prime[j]==0) { mu[i*prime[j]]=0; break; } else mu[i*prime[j]]=-mu[i]; } } for (int i=1;i<=k;++i) mu[i]+=mu[i-1]; } LL getmu(int x) { if (x<=k) return mu[x]; return sum[n/x]; } void summu() { int t; for (t=1;n/t>k;++t); for (;t;--t) { int m=n/t; sum[t]=1; for (int i=2,j=0;i<=m;i=j+1) { j=m/(m/i); sum[t]-=getmu(m/i)*(LL)(j-i+1); sum[t]%=Mod; } } } LL f(int n) { LL ans=0; for (int i=1,j=0;i<=n;i=j+1) { j=n/(n/i); ans+=(LL)(j-i+1)*(n/i)%Mod; ans%=Mod; } return ans*ans%Mod; } int main() { scanf("%d",&n); get();summu(); for (int i=1,j=0;i<=n;i=j+1) { j=n/(n/i); ans+=f(n/i)*(getmu(j)-getmu(i-1))%Mod; ans%=Mod; } ans=(ans+Mod)%Mod; printf("%lld\n",ans); }

相關推薦

[BZOJ4176]Lucas數論+

題目描述 傳送門 題解 做約數個數和的時候有一個結論: d(nm)=∑i|n∑j|m[(i,j)=1] 直接套進去 ∑i=1n∑j=1m∑x|i∑y|j[(x,y)=1] 然後根據反演公式

[BZOJ4652/UOJ#221][NOI2016]迴圈之美+

Address Solution…… 一、 O(nm)O(nm) 我們知道, kk 進位制小數 0.0000000...10000000..10000000..1...0.0000000...10000000..10000000..1... (迴圈

bzoj 4176: Lucas數論+

+= span ios bool names div display pac stream 首先由這樣一個結論: \[ d(ij)=\sum_{p|i}\sum_{q|j}[gcd(p,q)==1] \] 然後推反演公式: \[ \sum_{i=1}^{n}\sum_{j=

hdu5608 function (+

題目連結 題意:根據式子 求 想出這題的做法後看了幾個部落格想驗證一下,然而看了四五篇部落格發現博主的做法都和我不一樣...用自己的想法AC後,發現時間比大部分程式碼快,直接到rank2,然後略微優化了一下線性篩預處理部分(理論上預處理到n的2/3次方也就是1e

bzoj4176Lucas數論 +

wid eight 前綴 .html != brush name load ans 題目描述 去年的Lucas非常喜歡數論題,但是一年以後的Lucas卻不那麽喜歡了。 在整理以前的試題時,發現了這樣一道題目“求Sigma(f(i)),其中1<=i<

bzoj4176Lucas數論 +

n) ace sca \n 一行 分塊 cpp jpg bre Description 去年的Lucas非常喜歡數論題,但是一年以後的Lucas卻不那麽喜歡了。 在整理以前的試題時,發現了這樣一道題目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i

BZOJ 4176: Lucas數論(+)

alt 思路 難了 lol cst 每一個 r+ 去年 ons Description 去年的Lucas非常喜歡數論題,但是一年以後的Lucas卻不那麽喜歡了。 在整理以前的試題時,發現了這樣一道題目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i

[CQOI2015]選數bzoj3930 ++累加有上下界

題目: [CQOI2015]選數   題意:   思路: 若L%k==0,那麼累加的下界為 ,若L%k!=0,那麼累加的下界為  ,綜合一下,下界為 。 我們設下界 = t 。 原式 =   設 設

2018徐州ICPC網路賽D Easy Math /

遞推題解 #include<stdio.h> #include<string.h> #include<map> #include<algorithm> using namespace std; const int MAX=

[luogu]P3768 簡單的數學題(,)

題意 求,答案膜素數 資料範圍: 題解 設 如果所以尤拉函式和狄利克雷卷積,可以知道(我一開始也沒反應過來,可以設為進一步推導) ,可以整除分塊求,問題就變為化解(特指杜教篩操作) 設,為積性函式, 由杜教篩 那麼 就可以快速求得字首積了(預處

NOI 2016 循環之美 (+)

tar main 說明 pan == amp loj 個數 efi 題目大意:略 洛谷傳送門 鑒於洛谷最近總崩,附上良心LOJ鏈接 任何形容詞也不夠贊美這一道神題 $\sum\limits_{i=1}^{N}\sum\limits_{j=1}^{M}[gcd(i,

[+] 51Nod1237: 最大公約數之和 V3

題意 求∑ni∑njgcd(i,j) n≤1010 題解 ∑in∑jngcd(i,j)=∑d=1n∑i=1n∑j=1n[gcd(i,j)=d]∗d=∑d=1n∑i=1⌊nd⌋∑j=1⌊nd⌋

[聯合集訓6-12] Fraction ++類歐幾里得

因為區間可以差分成字首,我們只用考慮≤ab≤ab的最簡真分數jiji的個數。 Ans=∑1≤j<i≤n[j≤aib][gcd(i,j)=1]Ans=∑1≤j<i≤n[j≤aib][gcd(i,j)=1] 莫比烏斯反演, ∑1≤j<i≤n[

【BZOJ4815】[CQOI2017]小Q的表格,分塊

【BZOJ4815】[CQOI2017]小Q的表格(莫比烏斯反演,分塊) 題面 BZOJ 洛谷 題解 神仙題啊。 首先\(f(a,b)=f(b,a)\)告訴我們矩陣只要算一半就好了。 接下來是\(b*f(a,a+b)=(a+b)*f(a,b)\) 這個式子怎麼看呢? \[\begin{aligned}

BZOJ 3529 數表 +樹狀陣列*

#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #def

TrickGCD+容斥定理

連結:http://acm.hdu.edu.cn/showproblem.php?pid=6053 hdu6053 TrickGCD 題目解析: 令sum[k]為k能夠出現的個數 eg: Input 3 6 6 9 各個數字出現的情況 1 1 1 2 2 2 3 3

bzoj2301 [HAOI2011]Problem b求gcd==k的個數+容斥原理

首先我們搞掉下界,怎麼搞呢,用容斥原理即可。(看做矩形區間),然後我們需要求∑x=1n∑y=1ngcd(x,y)==k。 ∑x=1⌊n/k⌋∑y=1⌊m/k⌋gcd(x,y)==1 ∑x=1⌊n/k

HDU 5663 Hillan and the girl+分塊求和

大致題意:給你兩個數字n和m,讓你求,其中f(i,j)表示gcd(i,j)是否為完全平方數,如果是則f(i,j)==0,否則為f(i,j)==1。 首先,有了之前 BZOJ 2301 的經驗,這道題目可以比較簡單的講。BZOJ 2301 這題是求一定範圍內的兩個

HDU 6134 && 2017 多校訓練:Battlestation Operational+積性函式

實在太長了直接放題目連結 這題就是求 考慮當Gcd(i, j)==1時,除了j為1的情況,其它時候i/j一定是小數,所以i/j向上取整相當於向下取整的結果+1 那麼有:(其中φ(i)為小於i與i