Submit: 2068 Solved: 834
[Submit][Status][Discuss]
Description
Input
一个正整数T表示数据组数
接下来T行 每行两个正整数 表示N、M
Output
T行 每行一个整数 表示第i组数据的结果
Sample Input
1
4 5
4 5
Sample Output
122
HINT
T <= 10000
N, M<=10000000
HINT
T <= 10000
N, M<=10000000
HINT
Source
Orz gxz
这题好神仙啊,就是把这个换成了多组询问
我们可以继续利用上一个题的公式推
$f(n)$是两个积性函数的乘积,同样也是积性函数
考虑只有一个素因子时$f(n) = n * (1 - n)$
当$n$不为质数时$n = i * p$,此时$n$一定包含$p^2$这个因子,所以$f(n) = p * f(i)$
#include<cstdio> #include<algorithm> #define LL long long using namespace std; const int MAXN = 1e7 + 10, mod = 100000009; int T, N, M; int tot, vis[MAXN]; LL f[MAXN], prime[MAXN]; void GetF(int N) { f[1] = 1; for(int i = 2; i <= N; i++) { if(!vis[i]) prime[++tot] = i, f[i] = (i - 1ll * i * i % mod + mod) % mod; for(int j = 1; j <= tot && i * prime[j] <= N; j++) { vis[i * prime[j]] = 1; if(!(i % prime[j])) { f[i * prime[j]] = f[i] * prime[j] % mod; break; } else f[i * prime[j]] = f[i] * f[prime[j]] % mod; } } for(int i = 2; i <= N; i++) f[i] = (f[i - 1] + f[i] + mod) % mod; } LL S(LL x) { return (x * (x + 1)) / 2 % mod; } int main() { scanf("%d", &T); GetF(1e7 + 1); while(T--) { int N, M, last; LL ans = 0; scanf("%d %d", &N, &M); if(N > M) swap(N, M); for(int i = 1; i <= N; i = last + 1) { last = min(N / (N / i), M / (M / i)); ans = (ans + S(N / i) * S(M / i) % mod * (f[last] - f[i - 1] + mod) % mod) % mod; } printf("%lld ", ans); } return 0; } /* 2 4 5 123456 654321 */