题目:http://acm.nenu.edu.cn/regional-2015/files/2015/10/problemset_20151015.pdf
题意:
令 f(m) 表示满足 0≤a,b<m 且 m∤ab 的二元组 (a,b) 的个数。
令 g(n)=∑m|nf(m) ,询问 T 次某个 g(n) 的值,答案模 264 。
T≤20000,n≤109 。
题解:
(64位无符号整型变量的运算可以看做是在模 264 意义下的运算)
看到 g(n) 的形式很容易想到一个事实,如果 f(m) 是积性函数,即”对于互质的 a 和 b ,有 f(ab)=f(a)⋅f(b) ”,那么 g(n) 的表达式可以做到如下的改写:
令 n=pk11⋅pk22⋯pktt ,那么
代码:
#include <cstdio>
typedef unsigned long long ULL;
const int maxn = 32000;
int tot, prime[maxn], t, n;
bool vis[maxn];
ULL ans1, ans2;
int main()
{
for(int i = 2; i < maxn; ++i)
{
if(!vis[i])
prime[tot++] = i;
for(int j = 0, o; j < tot && (o = i * prime[j]) < maxn; ++j)
{
vis[o] = 1;
if(i % prime[j] == 0)
break;
}
}
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
ans1 = ans2 = 1;
for(int i = 0; i < tot && prime[i] * prime[i] <= n; ++i)
if(n % prime[i] == 0)
{
int cnt = 0, tmp = 1;
ULL sum = 1;
for( ; n % prime[i] == 0; n /= prime[i], ++cnt);
for(int j = 1; j <= cnt; ++j)
{
tmp *= prime[i];
sum += (ULL)tmp * tmp;
}
ans1 *= sum;
ans2 *= tmp * (cnt + 1ULL);
}
if(n > 1)
{
ans1 *= (ULL)n * n + 1;
ans2 *= n * 2ULL;
}
printf("%llu\n", ans1 - ans2);
}
return 0;
}
然而会做这道题也不能拿金。