mobius初步
-
求 ∑i=1n∑j=1m(gcd(i,j)==1)\sum_{i = 1} ^{n} \sum_{j = 1} ^{m} (gcd(i, j) == 1)∑i=1n?∑j=1m?(gcd(i,j)==1)
我們引入一個知識∑d∣nμ(d)=(n==1)\sum_{d \mid n} \mu(d) = (n == 1)∑d∣n?μ(d)=(n==1)
所以gcd(i,j)=∑d∣gcd(i,j)μ(d)gcd(i, j) = \sum_{d \mid gcd(i, j)} \mu(d)gcd(i,j)=∑d∣gcd(i,j)?μ(d)
對上式進行化簡:
=∑i=1n∑j=1m∑d∣gcd(i,j)μ(d)= \sum_{i = 1} ^{n} \sum_{j = 1} ^{m} \sum_{d\mid gcd(i, j)} \mu(d)=i=1∑n?j=1∑m?d∣gcd(i,j)∑?μ(d)
=∑d∣nμ(d)∑i=1nd∑j=1md1= \sum_{d \mid n} \mu(d) \sum_{i = 1} ^{\frac{n}ze8trgl8bvbq} \sum_{j = 1}^{\frac{m}ze8trgl8bvbq}1=d∣n∑?μ(d)i=1∑dn??j=1∑dm??1
∑d=1nμ(d)ndmd\sum_{d = 1} ^{n} \mu(d) \frac{n}ze8trgl8bvbq \frac{m}ze8trgl8bvbqd=1∑n?μ(d)dn?dm?
最后利用整除分塊求得最后的答案
-
求∑i=1n∑j=1m(gcd(i,j)==k)\sum_{i = 1} ^{n} \sum_{j = 1} ^{m} (gcd(i, j) == k)∑i=1n?∑j=1m?(gcd(i,j)==k)
=∑i=1nk∑j=1md(gcd(i,j)==1)= \sum_{i = 1} ^{\frac{n}{k}} \sum_{j = 1} ^{\frac{m}ze8trgl8bvbq} (gcd(i, j) == 1)=i=1∑kn??j=1∑dm??(gcd(i,j)==1)
另n′=nk,m′=mkn' = \frac{n}{k}, m' = \frac{m}{k}n′=kn?,m′=km?,所以如上式:
P3455 [POI2007]ZAP-Queries
上面式子的模板題,就不過多講解了,直接上代碼
/*Author : lifehappy */ // #pragma GCC optimize(2) // #pragma GCC optimize(3) #include <bits/stdc++.h>#define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1using namespace std;typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii;const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f;inline ll read() {ll x = 0, f = 1; char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return x * f; }const int N = 5e4 + 10;int mu[N], a, b, d;bool st[N];vector<int> prime;void mobius() {st[1] = st[0] = mu[1] = 1;for(int i = 2; i < N; i++) {if(!st[i]) {prime.pb(i);mu[i] = -1;}for(int j = 0; j < prime.size() && i * prime[j] < N; j++) {st[i * prime[j]] = 1;if(i % prime[j] == 0) {mu[i * prime[j]] = 0;break;}mu[i * prime[j]] = -mu[i];}}for(int i = 1; i < N; i++) mu[i] += mu[i - 1]; }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);mobius();int T = read();while(T--) {a = read(), b = read(), d = read();int n = a /= d, m = b /= d;if(n > m) swap(n, m);ll ans = 0;for(int l = 1, r; l <= n; l = r + 1) {r = min(n / (n / l), m / (m / l));ans += 1ll * (mu[r] - mu[l - 1]) * (n / l) * (m / l);}printf("%lld\n", ans);}return 0; }P2522 [HAOI2011]Problem b
也是是模板題,只是稍加改動,類似于前綴和的取法,最后得到我們的答案。
/*Author : lifehappy */ // #pragma GCC optimize(2) // #pragma GCC optimize(3) #include <bits/stdc++.h>#define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1using namespace std;typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii;const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f;inline ll read() {ll x = 0, f = 1; char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return x * f; }const int N = 5e4 + 10;int mu[N], a, b, c, d, k;bool st[N];vector<int> prime;void mobius() {st[1] = st[0] = mu[1] = 1;for(int i = 2; i < N; i++) {if(!st[i]) {prime.pb(i);mu[i] = -1;}for(int j = 0; j < prime.size() && i * prime[j] < N; j++) {st[i * prime[j]] = 1;if(i % prime[j] == 0) {mu[i * prime[j]] = 0;break;}mu[i * prime[j]] = -mu[i];}}for(int i = 1; i < N; i++) mu[i] += mu[i - 1]; }ll solve(int a, int b, int d) {int n = a /= d, m = b /= d;if(n > m) swap(n, m);ll ans = 0;for(int l = 1, r; l <= n; l = r + 1) {r = min(n / (n / l), m / (m / l));ans += 1ll * (mu[r] - mu[l - 1]) * (n / l) * (m / l);}return ans; }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);mobius();int T = read();while(T--) {a = read(), b = read(), c = read(), d = read(), k = read();ll ans = solve(b, d, k) + solve(a - 1, c - 1, k) - solve(a - 1, d, k) - solve(b, c - 1, k);printf("%lld\n", ans);}return 0; }-
∑i=1n∑j=1mij(gcd(i,j)==k)\sum_{i = 1} ^{n} \sum_{j = 1} ^{m} ij(gcd(i, j) == k)∑i=1n?∑j=1m?ij(gcd(i,j)==k)
=k2∑i=1nk∑j=1mkij(gcd(i,j)==1)= k ^ 2\sum_{i = 1} ^{\frac{n}{k}} \sum_{j = 1} ^{\frac{m}{k}}ij(gcd(i, j) == 1)=k2i=1∑kn??j=1∑km??ij(gcd(i,j)==1)
=k2∑i=1nk∑j=1mkij∑d∣gcd(i,j)μ(d)= k ^ 2\sum_{i = 1} ^{\frac{n}{k}} \sum_{j = 1} ^{\frac{m}{k}}ij\sum_{d\mid gcd(i, j)} \mu(d)=k2i=1∑kn??j=1∑km??ijd∣gcd(i,j)∑?μ(d)
=k2∑d=1nkμ(d)∑i=1nk∑j=1mkij= k ^ 2\sum_{d = 1} ^{\frac{n}{k}} \mu(d)\sum_{i = 1} ^{\frac{n}{k}} \sum_{j = 1} ^{\frac{m}{k}}ij=k2d=1∑kn??μ(d)i=1∑kn??j=1∑km??ij
=k2∑d=1nkμ(d)d2∑i=1nkd∑j=1mkdij= k ^ 2\sum_{d = 1} ^{\frac{n}{k}} \mu(d)d ^ 2\sum_{i = 1} ^{\frac{n}{kd}} \sum_{j = 1} ^{\frac{m}{kd}}ij=k2d=1∑kn??μ(d)d2i=1∑kdn??j=1∑kdm??ij
∑i=1nkd∑j=1mkdij\sum_{i = 1} ^{\frac{n}{kd}} \sum_{j = 1} ^{\frac{m}{kd}}ij∑i=1kdn??∑j=1kdm??ij這一項可以通過整除分塊得到,最后再統計一遍答案就行。
總結
- 上一篇: 减肥晚上吃什么瘦得快
- 下一篇: 女生减肥每天摄入多少