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

posted @ 2020-08-07 21:44  xzx9  阅读(186)  评论(0编辑  收藏  举报