設φ (x
)\varphi(x)
φ(x)
的字首和為s(x
)s(x)
s(x)
有乙個關於尤拉函式的性質:
∑ d∣
nφ(d
)=
n\sum_\varphi(d)=n
d∣n∑φ
(d)=
n這樣來做:
n (n
+1)2
=∑i=
1n∑d
∣iφ(
d)
\frac=\sum_^n\sum_\varphi(d)
2n(n+1
)=i
=1∑n
d∣i
∑φ(
d)到這裡很多同學會把d
dd提前,最終化簡成這個樣子:
∑ d=
1nφ(
d)⌊n
d⌋
\sum_^n\varphi(d)\lfloor\frac\rfloor
d=1∑n
φ(d)
⌊dn
⌋上面這個式子對我們求字首和似乎沒有什麼幫助,以下介紹另一種技巧:
n (n
+1)2
=∑k=
1n∑d
=1⌊n
k⌋φ(
d)=∑
k=1n
s(⌊n
k⌋
)\frac=\sum_^n\sum_^\rfloor}\varphi(d)=\sum_^ns(\lfloor\frac\rfloor)
2n(n+1
)=k
=1∑n
d=1
∑⌊kn
⌋φ
(d)=
k=1∑
ns(
⌊kn
⌋)其中k
kk代表了原式中i
ii是d
dd的幾倍
s (n
)=n(
n+1)
2−∑k
=2ns
(⌊nk
⌋)
s(n)=\frac-\sum_^ns(\lfloor\frac\rfloor)
s(n)=2
n(n+
1)−
k=2∑
ns(
⌊kn
⌋)到這裡,如果直接用類似記憶化搜尋的方式求解,時間複雜度是o(n
34
)o(n^\frac)
o(n43
)的,如果預處理s(0
)s(0)
s(0)
到s (n
23
)s(n^\frac)
s(n32
),最終的複雜度是o(n
23
)o(n^\frac)
o(n32
)時間複雜度的計算可能要用到大學知識,以我現在的水平還無法理解。
顯然我們預處理使用線性篩,這一部分的和直接用陣列連續儲存即可,但是我們在記憶化的過程中,當x
xx大於n23
n^\frac
n32
時,肯定沒法用s[x
]s[x]
s[x]
直接儲存。注意到⌊nx
⌋\lfloor\frac\rfloor
⌊xn⌋在x∈[
n,n]
x\in[\sqrt n,n]
x∈[n,
n]時有最多n
\sqrt n
n個取值,因此可以開乙個數量級在n
\sqrt n
n的陣列來儲存這些值,實際的s(x
)s(x)
s(x)
對應的下標為n/x
n/xn/
x。這樣為什麼對呢?多個x
xx不會對應乙個值嗎?經過考慮,發現我們具體在做的時候是分塊的,用到的x
xx一定都是n/k
n/kn/
k的形式,而k
kk是這個塊的左端點 ,那麼n/x
=n/(
n/k)
n/x=n/(n/k)
n/x=n/
(n/k
)就對應了這個塊的右端點,而n/x
n/xn/
x本身被分成哪些塊是一定的。計算過程中可能出現⌊na
⌋=⌊n
b⌋
\lfloor\frac\rfloor=\lfloor\frac\rfloor
⌊an⌋=
⌊bn
⌋,對應的分母不同,但取整後的結果是一樣的,這個值會被存在s(n
/(n/
a)
)s(n/(n/a))
s(n/(n
/a))
中,也就是s(n
/(n/
b)
)s(n/(n/b))
s(n/(n
/b))
中。
//杜教篩
#include #include #define ll long long
#define maxn 1587410
using namespace std;
ll phi[maxn], f[maxn], prime[maxn], n;
bool mark[maxn];
void init()
}int main()
BZOJ4805 尤拉函式求和
bzoj4805 尤拉函式求和 給出乙個數字n,求sigma phi i 1 i n 正整數n。n 2 10 9 輸出答案。1032 題目要求 sum n varphi i 這。不是很顯然乙個線性篩然後字首和就沒了麼?水題?並不!n leq 2 times 10 9 直接 tle 到 怎麼辦?沒事,...
BZOJ4805 尤拉函式求和
題目大意 對於給定的 n n leq2 times10 9 求 sum n varphi i 思路 設 s n sum n varphi i 因為 sum varphi d n s n sum n i sum 13const int n 1587402,m 120256 14 bool vis n ...
BZOJ 4805 尤拉函式求和
解題思路類似莫比烏斯函式之和 題目大意 求 1,n 內的尤拉函式 varphi 之和。n 2 10 思路 令 m n sum varphi i 題目所求即為 m n 由於 sum varphi d n 所以 sum sum varphi d frac 令 i kd 則有 sum sum varphi...