积性函数板刷1
A-线性筛求积性函数
求正整数 $n$ 的所有正因数的个数,$q$ 次询问。
第一行一个正整数 $q\ (1\leq q\leq 10^5)$ 。
第二行到第 $q+1$ 行,每行一个正整数 $n\ (1\leq n\leq 10^7)$。
code
// NowCoder 模板题【线性筛求积性函数】
// https://ac.nowcoder.com/acm/contest/22769/A 2024-03-28 21:02:44
#include <bits/stdc++.h>
using namespace std;
#define all(a) begin(a), end(a)
#define int long long
int n, m;
constexpr int N = 1E7 + 10;
int primes[N], tot;
int st[N], f[N];
void init() {
f[1] = 1;
for (int i = 2; i < N; i++) {
if (!st[i]) {
primes[++tot] = i;
f[i] = 2;
}
for (int j = 1, cnt = 0; j <= tot and i primes[j] < N; j++) {
st[i primes[j]] = true;
if (i % primes[j] == 0) {
int w = i;
while (w % primes[j] == 0) cnt++, w /= primes[j];
f[i primes[j]] = f[i] / (cnt + 1) (cnt + 2);
break;
} else
f[i primes[j]] = f[i] 2;
}
}
}
void solve() {
cin >> n;
cout << f[n] << "\n";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
init();
int __;
cin >> __;
while (__--) solve();
return 0;
}
C-序列
THINK
F(n)
为gcd(x,y)为n的倍数的有序对的对数
f(n)
为gcd(x,y)为n的有序对的对数
$$
\begin{align}
Ans&=\sum \limits _{1≤x≤n,1≤y≤n}[gcd(x,y)=1]⋅[a_{b_x}=b_{a_y}]\\
F(n)&=\sum\limits _{n|d}f(d)\\
f(n)&=\sum\limits _{n|d}\mu(\frac d n)\times F(d)\\
\end{align}
$$
最后求出f(1)
code
// NowCoder 序列
// https://ac.nowcoder.com/acm/contest/22769/C 2024-03-28 21:41:19
#include <bits/stdc++.h>
using namespace std;
#define all(a) begin(a), end(a)
#define int long long
constexpr int N = 1E5 + 10;
int primes[N], tot;
int st[N], mu[N], F[N];
void init(int N) {
mu[1] = 1;
for (int i = 2; i <= N; i++) {
if (!st[i]) {
primes[++tot] = i;
mu[i] = -1;
}
for (int j = 1; j <= tot and i * primes[j] <= N; j++) {
st[i * primes[j]] = true;
if (i % primes[j] == 0) {
mu[i * primes[j]] = 0;
break;
} else
mu[i * primes[j]] = -mu[i];
}
}
}
int n, m;
void solve() {
cin >> n;
init(n);
vector<int> a(n + 1);
vector<int> b(n + 1);
vector<int> cnt(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j += i) {
cnt[a[b[j]]]++;
}
for (int j = i; j <= n; j += i) {
F[i] += cnt[b[a[j]]];
}
for (int j = i; j <= n; j += i) {
cnt[a[b[j]]]--;
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += mu[i] * F[i];
}
cout << ans << "\n";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
solve();
return 0;
}