日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P2522 HAOI2011 Problem b [莫比乌斯反演,数论分块]

發(fā)布時(shí)間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P2522 HAOI2011 Problem b [莫比乌斯反演,数论分块] 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

P2522 HAOI2011

題意

對(duì)于給出的n個(gè)詢問,每次求有多少個(gè)數(shù)對(duì)(x,y)(x,y)(x,y),滿足a≤x≤ba≤x≤baxbc≤y≤dc≤y≤dcyd,且gcd(x,y)=kgcd(x,y) = kgcd(x,y)=kgcd(x,y)gcd(x,y)gcd(x,y)函數(shù)為xxxyyy的最大公約數(shù).

題解

即求式子∑x=ab∑y=cd[gcd(x,y)=k]\sum_{x=a}^b\sum_{y=c}^d[gcd(x,y)=k]x=ab?y=cd?[gcd(x,y)=k].

f(n,m)=∑x=1n∑y=1m[gcd(x,y)=k]f(n,m)=\sum_{x=1}^n\sum_{y=1}^m[gcd(x,y)=k]f(n,m)=x=1n?y=1m?[gcd(x,y)=k]

根據(jù)二維前綴和公式,可以將式子轉(zhuǎn)換成:

∑x=ab∑y=cd[gcd(x,y)=k]=f(b,d)+f(a?1,c?1)?f(a?1,d)?f(b,c?1)\sum_{x=a}^b\sum_{y=c}^d[gcd(x,y)=k]=f(b,d)+f(a-1,c-1)-f(a-1,d)-f(b,c-1)x=ab?y=cd?[gcd(x,y)=k]=f(b,d)+f(a?1,c?1)?f(a?1,d)?f(b,c?1)

因此我們只要能得到f(n,m)f(n,m)f(n,m)的計(jì)算方法即可.

f(n,m)f(n,m)f(n,m)的套路非常明顯:莫比比烏斯反演

由于∑k∣d∑x=1n∑y=1m[gcd(x,y)=d]=?nk??mk?\sum_{k|d}\sum_{x=1}^n\sum_{y=1}^m[gcd(x,y)=d] = \lfloor \frac{n}{k} \rfloor \lfloor \frac{m}{k} \rfloorkd?x=1n?y=1m?[gcd(x,y)=d]=?kn???km??.

反演得到f(n,m)=∑k∣dμ(dk)?nd??md?f(n,m)=\sum_{k|d}\mu(\fracozvdkddzhkzd{k})\lfloor \frac{n}ozvdkddzhkzd \rfloor \lfloor \frac{m}ozvdkddzhkzd \rfloorf(n,m)=kd?μ(kd?)?dn???dm??

t=d/kt = d/kt=d/k.

f(n,m)=∑t=1n/dμ(t)?nkt??mkt?f(n,m)=\sum_{t=1}^{n/d}\mu(t)\lfloor \frac{n}{kt} \rfloor \lfloor \frac{m}{kt} \rfloorf(n,m)=t=1n/d?μ(t)?ktn???ktm??

對(duì)上式子進(jìn)行分塊計(jì)算,可以將時(shí)間復(fù)雜度從O(n)O(n)O(n)降至O(n)O(\sqrt{n})O(n?).

總結(jié)

對(duì)于形如f(x)=∑x∣dμ(dx)g(?nd?)f(x)=\sum_{x|d}\mu(\fracozvdkddzhkzd{x})g(\lfloor \frac{n}ozvdkddzhkzd \rfloor)f(x)=xd?μ(xd?)g(?dn??)這樣的式子,我們都可以用t=d/xt=d/xt=d/x代換后數(shù)論分塊進(jìn)行加速.

f(x)=∑t=1n/xμ(t)g(?nxt?)f(x)=\sum_{t=1}^{n/x}\mu(t)g(\lfloor \frac{n}{xt} \rfloor)f(x)=t=1n/x?μ(t)g(?xtn??)

時(shí)間復(fù)雜度從O(n)O(n)O(n)降至O(n)O(\sqrt{n})O(n?).

代碼

#include <iostream> #include <algorithm> #include <cstring> #define pr(x) std::cout << #x << ':' << x << std::endl #define rep(i,a,b) for(int i = a;i <= b;++i)const int N = 50000;int prime[N+10],zhi[N+10],mu[N+10],pcnt;void sieve() {zhi[1] = mu[1] = 1;for(int i = 2;i <= N;++i) {if(!zhi[i]) {mu[i] = -1;prime[pcnt++] = i;}for(int j = 0;j < pcnt && prime[j]*i <= N;++j) {zhi[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 <= N;++i) mu[i] += mu[i-1]; } int a,b,c,d,k,T; int calc(int n,int m) {int ans = 0;int lim = std::min(n/k,m/k);for(int i = 1,nx1,nx2,nxt;i <= lim;i=nxt+1) {nx1 = n/(n/i);nx2 = m/(m/i);nxt = nx1>nx2?nx2:nx1;ans += (mu[nxt]-mu[i-1])*(n/i/k)*(m/i/k);}return ans; } int main() {std::ios::sync_with_stdio(false);sieve();std::cin >> T;while(T--) {std::cin >> a >> b >> c >> d >> k;int ans = calc(b,d)+calc(a-1,c-1)-calc(a-1,d)-calc(b,c-1);std::cout << ans << std::endl;}return 0; }

總結(jié)

以上是生活随笔為你收集整理的P2522 HAOI2011 Problem b [莫比乌斯反演,数论分块]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。