A Very Easy Math Problem-2020杭电多校6
题意
给定 \(n,x,k\),求:
\[\sum_{a_1=1}^{n}{\sum_{a_2=1}^{n}{...\sum_{a_x=1}^{n}{\left( \prod_{j=1}^{x}{a_j^k} \right) f(gcd(a_1,a_2,...,a_x))*gcd(a_1,a_2,...,a_x)}}}
\]
其中,
\[f(x)=\begin{cases}
0 & \exists\ k>1,x\%k^2=0\\
1 & others
\end{cases}
\]
\(1≤t≤10^4,1≤k≤10^9,1≤x≤10^9,1≤n≤2×10^5\)
分析
推导
\[\begin{align}
ans & = \sum_{d=1}^{n}{d·f(d)\sum_{a_1=1}^{n}{\sum_{a_2=1}^{n}{...\sum_{a_x=1}^{n}{\left( \prod_{j=1}^{x}{a_j^k} \right) ·[gcd(a_1,a_2,...,a_x)==d]}}}}\\
& = \sum_{d=1}^{n}{d^{kx+1}·f(d)\sum_{a_1=1}^{\lfloor n/d \rfloor}{\sum_{a_2=1}^{\lfloor n/d \rfloor}{...\sum_{a_x=1}^{\lfloor n/d \rfloor}{\left( \prod_{j=1}^{x}{a_j^k} \right) ·[gcd(a_1,a_2,...,a_x)==1]}}}}\\
& = \sum_{d=1}^{n}{d^{kx+1}·f(d)\sum_{a_1=1}^{\lfloor n/d \rfloor}{\sum_{a_2=1}^{\lfloor n/d \rfloor}{...\sum_{a_x=1}^{\lfloor n/d \rfloor}{\left( \prod_{j=1}^{x}{a_j^k} \right) ·\sum_{t|a_1,t|a_2,...,t|a_x}{\mu(t)}}}}}\\
& = \sum_{d=1}^{n}{d^{kx+1}·f(d)\sum_{a_1=1}^{\lfloor n/d \rfloor}{a_1^k \sum_{a_2=1}^{\lfloor n/d \rfloor}{a_2^k\ ...\sum_{a_x=1}^{\lfloor n/d \rfloor}{a_x^k ·\sum_{t|a_1,t|a_2,...,t|a_x}{\mu(t)}}}}}\\
& = \sum_{d=1}^{n}{d^{kx+1}·f(d) \left(\sum_{i=1}^{\lfloor n/d \rfloor}{i^k} \right)^x \sum_{t|a_1,t|a_2,...,t|a_x}{\mu(t)}}\\
& = \sum_{d=1}^{n}{d^{kx+1}·f(d) \sum_{t=1}^{\lfloor n/d \rfloor}{\mu(t)} ·\left(\sum_{i=1}^{\lfloor n/dt \rfloor}{(it)^k} \right)^x }\\
\end{align}
\]
令 \(T=dt\),并改变枚举顺序
\[\begin{align}
ans & = \sum_{T=1}^{n}{\left( \sum_{i=1}^{\lfloor n/T \rfloor}{i^k} \right)^x · T^{kx} \sum_{d|T}{f(d)\mu(\frac{T}{d})d}}\\
\end{align}
\]
令 \(g(T)=\sum_{d|T}^{T}{f(d)\mu(\frac{T}{d})d}\),最终结果为:
\[ans= \sum_{T=1}^{n}{\left( \sum_{i=1}^{\lfloor n/T \rfloor}{i^k} \right)^x · T^{kx}·g(T)}\\
\]
代码实现
其中,\(g,f\) 函数可以 \(O(nlogn)\) 预处理出,\(O(n)\) 预处理出 \(T^{kx}·g(T)\) 的前缀和,然后利用分块对每个 \(n\) 进行 \(O(\sqrt{n})\) 求解,总的复杂度为:\(O(nlogn+t\sqrt{n})\)。一开始想预处理出全部的答案,但是超时了。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=2e5+5;
int t,k,x,n;
int prime[N],mu[N],cnt,f[N];
bool vis[N];
ll g[N],sum[N],pre[N];
void init()
{
memset(vis,false,sizeof(vis));
int maxn=2e5;
cnt=0;
mu[1]=1;
for(int i=2;i<=maxn;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prime[j]<=maxn;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
mu[i*prime[j]]=-mu[i];
}
}
for(int i=1;i<=maxn;i++) f[i]=1;
for(int i=2;i*i<=maxn;i++)//预处理f(k)
{
int t=i*i;
for(int j=t;j<=maxn;j+=t)
f[j]=0;
}
//预处理g函数
for(int i=1;i<=maxn;i++)//枚举d
{
for(int j=i;j<=maxn;j+=i)//T
g[j]=(g[j]+f[i]*mu[j/i]*i%mod+mod)%mod;
}
}
ll power(ll a,ll b)
{
ll res=1;
a%=mod;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
void solve()
{
int maxn=2e5;
ll tmp=0;
for(int i=1;i<=maxn;i++)
{
ll t=power(1LL*i,1LL*k);
tmp=(tmp+t)%mod;
sum[i]=power(tmp,1LL*x)%mod;
pre[i]=(pre[i-1]+power(t,1LL*x%(mod-1))*g[i]%mod+mod)%mod;//T^(kx)*g(T)的前缀和
}
}
int main()
{
init();
scanf("%d%d%d",&t,&k,&x);
solve();
while(t--)
{
scanf("%d",&n);
ll ans=0;
for(int l=1,r;l<=n;l=r+1)
{
r=min(n,n/(n/l));
ans=(ans+sum[n/l]*(pre[r]-pre[l-1])%mod+mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
参考博客:https://blog.csdn.net/weixin_44282912/article/details/107844614