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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

[POI2007]ZAP-Queries [HAOI2011]Problem b 莫比乌斯反演

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

1,[POI2007]ZAP-Queries

~~~題面~~~
題解: 首先列出式子:$$ans = \sum_{i = 1}^{n}\sum_{j = 1}^{m}[gcd(i, j) == d]$$
    $$[gcd(i, j) == d] = [gcd(\lfloor{\frac{i}ozvdkddzhkzd}\rfloor,\lfloor{\frac{j}ozvdkddzhkzd}\rfloor) == 1]$$
    所以原式 $$\Rightarrow \quad \sum_{i = 1}^{\lfloor{\frac{n}ozvdkddzhkzd}\rfloor}\sum_{j = 1}^{\lfloor{\frac{m}ozvdkddzhkzd}\rfloor}[gcd(i, j)==1]$$
    $$\Rightarrow \quad \sum_{i = 1}^{n}\sum_{j = 1}^{m}\sum_{d|gcd(i, j)}\mu(d)$$
    因?yàn)?\mu(d)$會(huì)被統(tǒng)計(jì)到當(dāng)且僅當(dāng)$d | i \quad and \quad d | j$,即$d | gcd(i, j)$
    那么考慮將滿足條件的i和j兩兩搭配,組成的方案數(shù)就是$\mu(d)$會(huì)被統(tǒng)計(jì)到的次數(shù),
    也就是$\mu(d)$會(huì)被統(tǒng)計(jì)到$\lfloor{\frac{n}ozvdkddzhkzd}\rfloor\lfloor{\frac{m}ozvdkddzhkzd}\rfloor$次
    $$\Rightarrow \quad ans=\sum_{i=1}^{min(n,m)}{\mu(d)\lfloor{\frac{n}ozvdkddzhkzd}\rfloor\lfloor{\frac{m}ozvdkddzhkzd}\rfloor}$$
    然后觀察到$\lfloor{\frac{n}ozvdkddzhkzd}\rfloor\lfloor{\frac{m}ozvdkddzhkzd}\rfloor$中有很多小段$\lfloor{\frac{n}ozvdkddzhkzd}\rfloor\lfloor{\frac{m}ozvdkddzhkzd}\rfloor$乘積是固定的,也就是$\lfloor{\frac{n}ozvdkddzhkzd}\rfloor$和$\lfloor{\frac{m}ozvdkddzhkzd}\rfloor$同時(shí)為一個(gè)固定的值,因此我們可以用整數(shù)分塊優(yōu)化

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define R register int 4 #define AC 55000 5 int t, n, m, d; 6 int prime[AC], mu[AC], sum[AC], tot; 7 bool z[AC]; 8 9 inline int read() 10 { 11 int x = 0;char c = getchar(); 12 while(c > '9' || c < '0') c = getchar(); 13 while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); 14 return x; 15 } 16 17 void getprime() 18 { 19 int now; 20 mu[1] = 1; 21 for(R i = 2; i <= 50000; i++) 22 { 23 if(!z[i]) prime[++tot] = i, mu[i] = -1; 24 for(R j = 1; j <= tot; j++) 25 { 26 now = prime[j]; 27 if(now * i > 50000) break; 28 // printf("!!!%d %d\n", now, i); 29 z[now * i] = true; 30 if(!(i % now)) break; 31 mu[i * now] = -mu[i]; 32 } 33 } 34 for(R i = 1; i <= 50000; i++) 35 sum[i] = mu[i] + sum[i - 1]; 36 } 37 38 int ans; 39 40 void work() 41 { 42 int pos; 43 t = read(); 44 for(R i = 1; i <= t; i++) 45 { 46 n = read(), m = read(), d = read(); 47 n /= d, m /= d; 48 int b = min(n, m); 49 ans = 0; 50 for(R j = 1; j <= b; j = pos + 1) 51 { 52 pos = min(n / (n / j), m / (m / j)); 53 ans += (sum[pos] - sum[j-1]) * (n / j) * (m / j); 54 } 55 printf("%d\n", ans); 56 } 57 } 58 59 int main() 60 { 61 // freopen("in.in", "r", stdin); 62 getprime(); 63 work(); 64 // fclose(stdin); 65 return 0; 66 } View Code

?


2,[HAOI2011]Problem b

~~~題面~~~
題解: 這題相比上題多出了兩個(gè)限制條件,同時(shí)對(duì)上下限都有限制,那么此時(shí)可以用一個(gè)容斥來(lái)求。
    設(shè)$cal(n,m)$表示滿足$x \le n$和$y \le m$且$gcd(x, y) = d$的點(diǎn)對(duì)個(gè)數(shù),
    那么$$ans = cal(b, d) - cal(a - 1, d) - cal(b, c - 1) + cal(a - 1, c - 1);$$

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define R register int 4 #define AC 55000 5 #define LL long long 6 int a, b, c, d, tot, k, t, ans; 7 int prime[AC], mu[AC], sum[AC]; 8 bool z[AC]; 9 10 inline int read() 11 { 12 int x = 0; char c = getchar(); 13 while(c > '9' || c < '0') c = getchar(); 14 while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); 15 return x; 16 } 17 18 void pre() 19 { 20 int now; 21 mu[1] = 1; 22 for(R i = 2; i <= 50000; i++) 23 { 24 if(!z[i]) prime[++tot] = i, mu[i] = -1;//質(zhì)數(shù)的mu值肯定都是-1 25 for(R j = 1; j <= tot; j++) 26 { 27 now = prime[j]; 28 if(now * i > 50000) break; 29 z[now * i] = true; 30 if(!(i % now)) break; 31 mu[i * now] = -mu[i];//error這里的mu是由mu[i]得來(lái)的啊!!! 32 } 33 } 34 for(R i = 1; i <= 50000; i++) sum[i] = sum[i - 1] + mu[i]; 35 } 36 37 int cal(int n, int m) 38 { 39 n /= k, m /= k; 40 int b = min(n, m), pos, rnt = 0; 41 for(R i = 1; i <= b; i = pos + 1) 42 { 43 pos = min(n / (n / i), m / (m / i)); 44 rnt += (sum[pos] - sum[i-1]) * (n / i) * (m / i); 45 } 46 return rnt; 47 } 48 //ans = cal(b, d) - cal(a - 1, d) - cal(b, c - 1) + cal(a - 1 , c - 1),相當(dāng)于容斥 49 50 void work() 51 { 52 t = read(); 53 for(R i = 1; i <= t; i++) 54 { 55 a = read(), b = read(), c = read(), d = read(), k = read(); 56 ans = cal(b, d) - cal(a - 1, d) - cal(b, c - 1) + cal(a - 1, c - 1); 57 printf("%d\n", ans); 58 } 59 } 60 61 int main() 62 { 63 // freopen("in.in", "r", stdin); 64 pre(); 65 work(); 66 // fclose(stdin); 67 return 0; 68 } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/ww3113306/p/9471558.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

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

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