1. 程式人生 > >HDU5608 function 【杜教篩】

HDU5608 function 【杜教篩】

題目描述

N 2 3 N + 2 =

d n f ( d ) N^2-3N+2=\sum_{d|n}f(d)

i = 1 n f (
i )    m o d    1 e 9 + 7 \sum_{i=1}^nf(i)~~mod~~1e9+7

多組資料, T 500 , N 1 0 9 T\le500,N\le10^9 ,至多5組資料   N > = 1 0 6 ~N>=10^6

題目分析

杜教篩其實就是用狄利克雷卷積優化
n 2 3 n + 2 n^2-3n+2 看作 g ( n ) g(n)
那麼可看出 f I = g f*I=g
倘若用於卷積的其中一個函式(此處的 I I )和卷積後的函式(此處的 g g )很好求字首和,那麼就可以優化求卷積中的另一個函式的字首和
i = 1 n g ( i ) = i = 1 n d i f ( d ) I ( i d )             = i = 1 n d = 1 n i f ( d ) I ( i ) \sum_{i=1}^ng(i)=\sum_{i=1}^n\sum_{d|i}f(d)*I({i\over d})\\~~~~~~~~~~~=\sum_{i=1}^n\sum_{d=1}^{\lfloor{n\over i}\rfloor}f(d)*I(i)
上式第二行中的 i i 實際上是在列舉第一行中 i i d d 的幾倍
這樣就使得 d d 連續,便於分塊優化,記 i = 1 n f ( i ) = F ( n ) \sum_{i=1}^nf(i)=F(n)
i = 1 n g ( i ) = i = 1 n d = 1 n i f ( d ) I ( i )             = i = 1 n F ( n i ) I ( i ) \sum_{i=1}^ng(i)=\sum_{i=1}^n\sum_{d=1}^{\lfloor{n\over i}\rfloor}f(d)*I(i)\\~~~~~~~~~~~=\sum_{i=1}^nF(\lfloor{n\over i}\rfloor)*I(i)
i = 1 i=1 移到左邊,g移到右邊,得到
F ( n ) I ( 1 ) = F ( n ) = i = 1 n g ( i )   i = 2 n F ( n i ) I ( i ) F(n)*I(1)=F(n)\\=\sum_{i=1}^ng(i) ~-\sum_{i=2}^nF(\lfloor{n\over i}\rfloor)*I(i)
g(i)可以O(1)求,F用分塊優化, O ( n 3 4 ) O(n^{3\over 4})

但是還是會TLE,需要線性篩出 n 1 0 6 n\le10^6 的F,時間複雜度可以降到 O ( n 2 3 ) O(n^{2\over 3})

f I = g f ( I μ ) = g μ f e = g μ f*I=g\\ f*(I*\mu)=g*\mu\\ f*e=g*\mu <