[HDU 5382] GCD?LCM!
Description
First we define:
(1) \(lcm(a,b)\), the least common multiple of two integers \(a\) and \(b\), is the smallest positive integer that is divisible by both \(a\) and \(b\). for example, \(lcm(2,3)=6\) and \(lcm(4,6)=12\).
(2) \(gcd(a,b)\), the greatest common divisor of two integers \(a\) and \(b\), is the largest positive integer that divides both \(a\) and \(b\) without a remainder, \(gcd(2,3)=1\) and \(gcd(4,6)=2\).
(3) \([exp]\), \(exp\) is a logical expression, if the result of \(exp\) is \(true\), then \([exp]=1\), else \([exp]=0\). for example, \([1+2≥3]=1\) and \([1+2≥4]=0\).
Now Stilwell wants to calculate such a problem:
Find \(S(n) \bmod 258280327\).
Input
The first line of the input contains a single number \(T\), the number of test cases.
Next \(T\) lines, each line contains a positive integer \(n\).
\(T≤10^5, n≤10^6\).
Output
\(T\) lines, find \(S(n) \bmod 258280327\).
Sample Input
8
1
2
3
4
10
100
233
11037
Sample Output
1
5
13
26
289
296582
3928449
213582482
Source
2015 Multi-University Training Contest 8
Solution
设
设
将 \(n\) 分解质因数,则一种质数要么全在 \(i\) 中,要么全在 \(\dfrac{n}{i}\) 中,因此 \(g(n)=2^m\),其中 \(m\) 是 \(n\) 的质因数个数。
则
Code
#include <cstdio>
const int N = 1000005, mod = 258280327;
int f[N], g[N], s[N], p[N], np[N], tot;
int read() {
int x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x;
}
void build(int n) {
for (int i = 2; i <= n; ++i) {
if (!np[i]) p[++tot] = i;
for (int j = 1; j <= tot && i * p[j] <= n; ++j) {
np[i * p[j]] = 1;
if (i % p[j] == 0) break;
}
}
for (int i = 1; i <= tot; ++i)
for (int j = p[i]; j <= n; j += p[i]) ++g[j];
for (int i = 1; i <= n; ++i) g[i] = 1 << g[i];
for (int i = 1; i <= n; ++i)
for (int j = i, k = 0; j <= n; j += i, ++k)
if ((f[j] += g[k]) >= mod) f[j] -= mod;
for (int i = 1; i <= n; ++i) {
s[i] = s[i - 1] + (i << 1) - 1 - f[i - 1];
if (s[i] < 0) s[i] += mod;
if (s[i] >= mod) s[i] -= mod;
}
for (int i = 2; i <= n; ++i) if ((s[i] += s[i - 1]) >= mod) s[i] -= mod;
}
int main() {
build(1000000);
for (int T = read(); T; --T) printf("%d\n", s[read()]);
return 0;
}