2024.7 做题记录

放暑假了 > <

P3935 Calculating

\(g(n) = \displaystyle \sum_{i=1}^n d(i)\),答案即为 \(g(r) - g(l - 1)\)

\[g(n) = \displaystyle \sum_{i = 1}^n \sum_{j = 1}^i[j | i] \]

考虑改变贡献方式,统计每个数会贡献到哪些 \(i \in [1, n]\)

\[g(n) = \sum_{i = 1}^n\lfloor \dfrac{n}{i} \rfloor \]

整除分块。

// 如果命运对你缄默, 那就活给他看。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; 
// #define int LL
LL l, r;
const int p = 998244353;
inline int g(LL n) {
	LL ans = 0;
	for(LL l = 1, r; l <= n; l = r + 1) {
		r = n / (n / l);
		ans = ans + (r - l + 1) * (n / l) % p; 
		ans  = ans % p;
	}
	return ans; 
}
signed main() {
	ios :: sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> l >> r;
	cout << (g(r) - g(l - 1) + p) % p << '\n';
	return 0;
}

P2261 [CQOI2007] 余数求和

\[\begin{aligned} \sum_{i = 1}^n k \bmod i =&\sum_{i = 1}^nk-i\lfloor \dfrac{n}{i} \rfloor\\ &=nk - \sum^{n}_{i = 1} i\lfloor \dfrac{n}{i} \rfloor \\ \end{aligned} \]

整除分块。

// 如果命运对你缄默, 那就活给他看。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; 
// #define int LL
int n, k; 	
inline LL G(int n, int k) {
	LL ans = 0;
	for(int l = 1, r; l <= min(n, k); l = r + 1) {
		r = min(n, k / (k / l));
		ans += 1LL * (k / l) * (l + r) * (r - l + 1) / 2;
	}
	ans = -ans + 1LL * n * k;
	return ans;
}
signed main() {
	ios :: sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n >> k;
	cout << G(n, k) << '\n';
	return 0;
}

P1829 [国家集训队] Crash的数字表格

首先有

\[h(n, m) = \sum_{i = 1}^n \sum_{j = 1}^m \text{lcm}(i, j) = \sum_{i = 1}^n \sum_{j = 1}^m \dfrac{ij}{\gcd(i, j)} \\ \]

然后考虑枚举 \(d = \gcd(i, j)\)

\[\sum_{i = 1}^n \sum_{j = 1}^m \sum_{d|i, d|j, \gcd(\frac{i}{d}, \frac{j}{d}) = 1}\dfrac{ij}{d} \]

改为枚举 \(\frac{i}{d}, \frac{j}{d}\),这样每一对都唯一对应到另一对

\[\begin{aligned} \sum_{d = 1}^n \sum_{i = 1}^{\lfloor \frac{n}{d}\rfloor} \sum_{j = 1}^{\lfloor \frac{m}{d}\rfloor}ijd[\gcd(i,j)=1] &=\sum_{d = 1}^n d\sum_{i = 1}^{\lfloor \frac{n}{d}\rfloor} \sum_{j = 1}^{\lfloor \frac{m}{d}\rfloor}ij[\gcd(i,j)=1]\\ \end{aligned}\]

后面的部分是一个矩形内的互质对之积,考虑设 \(f(n, m) =\displaystyle\sum_{i = 1}^{n} \sum_{j = 1}^{m}ij[\gcd(i,j)=1]\)

\([\gcd(i, j) = 1]\) 替换成 \(\varepsilon\),再莫反一下

\[\displaystyle\sum_{i = 1}^{n} \sum_{j = 1}^{m}\sum_{d | \gcd(i, j)}\mu(d) ij \\ \]

把这个枚举约数往外面拿

\[\displaystyle \sum_{d = 1} \sum_{i = 1}^{n} \sum_{j = 1}^{m}\mu(d) ij[d | i][d | j] \]

同样是枚举消掉 \(d\) 后的对

\[\displaystyle \sum_{d = 1} \mu(d) d^2 \sum_{i = 1}^{\lfloor \frac{n}{d}\rfloor} \sum_{j = 1}^{\lfloor \frac{m}{d}\rfloor}ij \]

后面这个东西可以拿出来做,有

\[g(n, m) = \sum_{i = 1}^n\sum_{j = 1}^mij \\ =\dfrac{(1 + n)n}{2} \times \dfrac{(1 + m)m}{2}\]

于是有

\[f(n, m) = \displaystyle \sum_{d = 1} \mu(d) d^2 g(\lfloor \frac{n}{d}\rfloor, \lfloor \frac{m}{d}\rfloor) \]

\[h(n, m) = \sum_{d = 1}^n d\ f(\lfloor \frac{n}{d}\rfloor, \lfloor \frac{m}{d}\rfloor) \]

分别整除分块即可,复杂度 \(O(n)\)

// 如果命运对你缄默, 那就活给他看。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; 
// #define int LL
const int maxn = 1e7 + 10;
const int p = 20101009;
int mu[maxn], pr[maxn], tot = 0, s[maxn];
inline void Euler() {
    mu[1] = 1;
    bitset <maxn> st;
    for(int i = 2; i < maxn; ++ i) {
        if(!st[i]) pr[++ tot] = i, mu[i] = -1;
        for(int j = 1; pr[j] * i < maxn && j <= tot; ++ j) {
            st[pr[j] * i] = 1;
            if(i % pr[j] == 0) {
                mu[i * pr[j]] = 0;
                break;
            }
            mu[pr[j] * i] = -mu[i];
        }
    }
    for(int i = 1; i < maxn; ++ i) {
        s[i] = 1LL * i * i % p * (mu[i] + p) % p;
        s[i] = (s[i] + s[i - 1]) % p;
    }
}
int n, m;
inline int g(int n, int m) {
    int p = (1LL * n + 1LL) * n / 2 % ::p,
        q = (1LL * m + 1LL) * m / 2 % ::p;
    return 1LL * p * q % ::p;
}
inline int f(int n, int m) {
    LL ans = 0;
    for(int l = 1, r; l <= min(n, m); l = r + 1) { 
        r = min(n / (n / l), m / (m / l));
        ans += 1LL * (s[r] - s[l - 1] + p) % p * g(n / l, m / l) % p;
        ans %= p;
    }
    return ans;
}
inline int h(int n, int m)  {
    int ans = 0;
    for(int l = 1, r; l <= min(n, m); l = r + 1) {
        r = min(n / (n / l), m / (m / l));
        ans += 1LL * (l + r) * (r - l + 1) / 2 % p * f(n / l, m / l) % p;
        ans %= p;
    }
    return ans;
}
signed main() {
    ios :: sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    Euler();
    cin >> n >> m;
    cout << h(n, m) << '\n';
    return 0;
}

BZOJ2693 jzptab

多组询问。

posted @ 2024-07-15 09:21  Rainsheep  阅读(136)  评论(0编辑  收藏  举报