\(T\) 组询问。一开始给定一个常数 \(m\)。每次询问单独给定 \(n\)。请你求出:
\(\sum_{i=1}^{n}\sum_{j=1}^{n} (i+j)^m \gcd(i,j) \mu^2(\gcd(i,j)) \pmod {2^{32}}\)
枚举k=(i,j)
\(\displaystyle \sum_{k}k\mu^{2}(k)\sum_{i=1}^{n/k}\sum_{j=1}^{n/k}(ik+jk)^m[(i,j)=1]\)
经典莫反
\(=\displaystyle \sum_{k}k\mu^{2}(k)\sum_{i=1}^{n/k}\sum_{j=1}^{n/k}(ik+jk)^m \sum_{d|i,d|j}\mu(d)\)
\(=\displaystyle \sum_{k}k\mu^{2}(k) \sum_{d}\sum_{i=1}^{n/kd}\sum_{j=1}^{n/kd}(ikd+jkd)^m\)
\(=\displaystyle \sum_{T}T^m\sum_{k|T}k\mu^2(k)\mu({\frac{T}{k}})\sum_{i=1}^{n/T}\sum_{j=1}^{n/T}(i+j)^m\)
设\(S(n)=\displaystyle \sum_{i=1}^{n}\sum_{j=1}^{n}(i+j)^m\)
将表格写出来之后
发现\(S(n)-S(n-1)\)是两段连续的数的k次方和。
所以我们只用求k次方和即可,而这个东西其实也是可以筛的。
对于
\(g(T)=\displaystyle\sum_{k|T}k\mu^2(k)\mu({\frac{T}{k}})\)
明显g是积性函数
考虑质因子\(p^c\)的贡献
- c=1,贡献为p-1
- c=2,贡献为-p
- \(c >2\) ,贡献为0
那么直接线筛即可。
#include<bits/stdc++.h>
#define fo(i,a,b) for (uint (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define eb emplace_back
#define pi pair<ll,ll>
#define mk(x,y) make_pair((x),(y))
#define lc (o<<1)
#define rc ((o<<1)|1)
//#define A puts("Yes")
//#define B puts("No")
#define fi first
#define se second
using namespace std;
typedef unsigned int uint;
typedef double db;
const int N=2e7+5;
const int M=1e6+5;
uint z[N],s[N];
long long g[N/2];
uint p[M],tot,n,m,f[N];
int cnt[N];
bool vis[N];
uint power(uint a,uint b){
uint t=1,y=a;
while (b) {
if (b&1) t=t*y;
y=y*y;
b/=2;
}
return t;
}
int main() {
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T;
cin>>T>>n>>m;
fo(i,2,n*2) {
if (!vis[i]) {
p[++tot]=i;
z[i]=power(i,m);
}
fo(j,1,tot) {
if (i*p[j]>=N) break;
vis[i*p[j]]=1;
z[i*p[j]]=z[i]*z[p[j]];
if (i%p[j]==0) break;
}
}
fo(i,2,n) {
if (!vis[i]) {
cnt[i]=1;
g[i]=i-1;
}
fo(j,1,tot) {
if (i*p[j]>n) break;
if (i%p[j]==0) {
if (cnt[i]>=2) g[i*p[j]]=0,cnt[i*p[j]]=3;
else if (cnt[i]==1) {
cnt[i*p[j]]=2;
g[i*p[j]]=g[i]/(p[j]-1)*(-p[j]);
}
break;
}
g[i*p[j]]=g[i]*(p[j]-1),cnt[i*p[j]]=1;
}
}
g[1]=1;
z[1]=1;
fo(i,2,n*2) z[i]=z[i]+z[i-1];
s[1]=power(2,m);
fo(i,2,n) s[i]=s[i-1]+z[2*i-1]-z[i]+z[2*i]-z[i];
fo(i,1,n) f[i]=f[i-1]+(z[i]-z[i-1])*(uint)g[i];
while (T--) {
cin>>n;
uint ans=0;
for (uint lt=1,rt;lt<=n;lt=rt+1) {
rt=n/(n/lt);
ans+=(f[rt]-f[lt-1])*s[n/lt];
}
cout<<ans<<"\n";
}
return 0;
}
总结:
- 自然数k次幂也是可以用筛法求的。
- 对于积性函数,可以讨论每个质因子\(p^c\)的贡献,然后乘起来。