BZOJ4407 於神之怒加強版 (數論 線性篩)

2021-08-16 18:34:47 字數 2059 閱讀 2322

題目傳送門:

題目分析:又是一道老年人數論題。

不妨令n≤m

n ≤m

。經過一番推導倒,可以得到這個:an

s=∑d

=1n⌊

nd⌋⌊

md⌋∑

d|dd

kμ(d

d)a ns

=∑d=

1n⌊n

d⌋⌊m

d⌋∑d

|ddk

μ(dd

)令g(

i)=i

k g(i

)=ik

,它是個完全積性函式,可以通過預處理所有質數的

g g

然後線性篩得到。求質數的

g' role="presentation" style="position: relative;">g

g值可以用快速冪。由於質數個數是nln

(n) nln⁡

(n

)級別的,所以這部分時間為o(

nlog(k

)ln(n

))o (n

log⁡(k

)ln⁡(

n)

)。又因為n,

k n,k

大小相近,可以認為接近o(

n)o (n

)。

第二個∑

後面的式子記為f(

d)f (d

),它是

g g

卷μ' role="presentation" style="position: relative;">μ

μ,所以也是積性函式。令

p p

為質數,則可以預處理全部f(

pq)' role="presentation" style="position: relative;">f(p

q)f(

pq),然後用線性篩得到所有

f f

值。根據定義顯然有f(

pq)=

g(pq

)−g(

pq−1

)' role="presentation" style="position: relative;">f(p

q)=g

(pq)

−g(p

q−1)

f(pq

)=g(

pq)−

g(pq

−1)。然後對於每個詢問下底函式分塊,總時間為o(

n+tn

−−√)

o (n

+tn)

。一開始g

g

陣列乘起來的時候忘了取模,wa了一次。

code:

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=5000010;

const

long

long m=1000000007;

typedef

long

long ll;

int p[maxn];

ll g[maxn];

ll f[maxn];

bool vis[maxn];

int prime[maxn];

int cur=0;

int t,n,m,k;

ll fast_power(ll x,ll y)

void linear_shaker()}}

f[1]=1ll;

for (int i=1; i<=cur; i++)

}for (int i=2; iif (p[i]for (int i=1; i1]+f[i])%m;

}int main()

printf("%i64d\n",ans);

}return

0;}

bzoj 4407 於神之怒加強版

time limit 80 sec memory limit 512 mb submit 624 solved 297 submit status discuss 給下n,m,k.求 輸入有多組資料,輸入資料的第一行兩個正整數t,k,代表有t組資料,k的意義如上所示,下面第二行到第t 1行,每行為兩...

bzoj 4407 於神之怒加強版

給下n,m,k.求 輸入有多組資料,輸入資料的第一行兩個正整數t,k,代表有t組資料,k的意義如上所示,下面第二行到第t 1行,每行為兩個正整數n,m,其意義如上式所示。如題1 2 3 3 20感覺是道比較水的數論題?提個d k隨手莫比烏斯反演一下,再把 跟d k放在一起,預處理出來就好了。瑪雅,1...

bzoj4407 於神之怒加強版

傳送門 題解 推一波公式 你還是需要前置技能 那麼好像可以o tnlogn 直接暴力啊!當然是兩遍根號分塊變成o tn 啊 好訊息過不去。當你莫比烏斯反演發現複雜度不對的話怎麼辦?繼續瞎 化簡!令x pd,那麼有 哎這個式子看起來很和善 後面那個好像是積性函式 逃 那麼線性篩就行啦!問題是怎麼篩呢。...