-
求 ∑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∑nj=1∑md∣gcd(i,j)∑μ(d)
=∑d∣nμ(d)∑i=1nd∑j=1md1= \sum_{d \mid n} \mu(d) \sum_{i = 1} ^{\frac{n}{d}} \sum_{j = 1}^{\frac{m}{d}}1=d∣n∑μ(d)i=1∑dnj=1∑dm1
∑d=1nμ(d)ndmd\sum_{d = 1} ^{n} \mu(d) \frac{n}{d} \frac{m}{d}d=1∑nμ(d)dndm
最后利用整除分块求得最后的答案
-
求∑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}{d}} (gcd(i, j) == 1)=i=1∑knj=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=1mij(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∑knj=1∑kmij(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∑knj=1∑kmijd∣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∑knj=1∑kmij
=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∑kdnj=1∑kdmij
∑i=1nkd∑j=1mkdij\sum_{i = 1} ^{\frac{n}{kd}} \sum_{j = 1} ^{\frac{m}{kd}}ij∑i=1kdn∑j=1kdmij这一项可以通过整除分块得到,最后再统计一遍答案就行。