[数论] HDU 6833 A very easy math problem

题目大意

给定正整数 \(n,x,k\),求

\[\sum_{a_1=1}^{n}\sum_{a_2=1}^n\dotsb\sum_{a_x=1}^n\left(\prod_{j=1}^xa_j^k\right)f\left(gcd\left(a_1,a_2,\dots,a_x\right)\right)\cdot gcd\left(a_1,a_2,\dots,a_x\right) \]

如果存在正整数 \(k(k>1)\),并且 \(k^2|x\),那么 \(f(x)=0\),否则 \(f(x)=1\)

\(1\leq k\leq 10^9,1\leq x\leq 10^9,1\leq n\leq 2\times10^5\)

题解

注意到 \(f(x)\) 的定义,显然 \(f(x)=\mu^2(x)\)
那么就是要求

\[\sum_{a_1=1}^{n}\sum_{a_2=1}^n\dotsb\sum_{a_x=1}^n\left(\prod_{j=1}^xa_j^k\right)\mu^2\left(gcd\left(a_1,a_2,\dots,a_x\right)\right)\cdot gcd\left(a_1,a_2,\dots,a_x\right) \]

首先枚举gcd

\[\sum_{d=1}^n\sum_{a_1=1}^{n}\sum_{a_2=1}^n\dotsb\sum_{a_x=1}^n\left(\prod_{j=1}^xa_j^k\right)\mu^2\left(d\right)\cdot d [d=gcd\left(a_1,a_2,\dots,a_x\right)] \]

\[\sum_{d=1}^n\mu^2\left(d\right)d\sum_{a_1=1}^{n}\sum_{a_2=1}^n\dotsb\sum_{a_x=1}^n\left(\prod_{j=1}^xa_j^k\right)[d=gcd\left(a_1,a_2,\dots,a_x\right)] \]

\[\sum_{d=1}^n\mu^2\left(d\right)d\sum_{a_1=1}^{n/d}\sum_{a_2=1}^{n/d}\dotsb\sum_{a_x=1}^{n/d}\left(\prod_{j=1}^x(a_jd)^k\right)[gcd\left(a_1,a_2,\dots,a_x\right)=1] \]

\[\sum_{d=1}^n\mu^2\left(d\right)d\sum_{a_1=1}^{n/d}\sum_{a_2=1}^{n/d}\dotsb\sum_{a_x=1}^{n/d}\left(\prod_{j=1}^x(a_jd)^k\right)\sum_{p|gcd(a_1,a_2,\dots,a_x)}\mu(p) \]

\[\sum_{d=1}^n\mu^2\left(d\right)d^{kx+1}\sum_{a_1=1}^{n/d}\sum_{a_2=1}^{n/d}\dotsb\sum_{a_x=1}^{n/d}\left(\prod_{j=1}^xa_j^k\right)\sum_{p|gcd(a_1,a_2,\dots,a_x)}\mu(p) \]

枚举 \(p\)

\[\sum_{d=1}^n\mu^2\left(d\right)d^{kx+1}\sum_{p=1}^{n/d}\mu(p)\sum_{a_1=1}^{n/dp}\sum_{a_2=1}^{n/dp}\dotsb\sum_{a_x=1}^{n/dp}\left(\prod_{j=1}^x(a_jp)^k\right) \]

\[\sum_{d=1}^n\mu^2\left(d\right)d^{kx+1}\sum_{p=1}^{n/d}\mu(p)p^{kx}\sum_{a_1=1}^{n/dp}\sum_{a_2=1}^{n/dp}\dotsb\sum_{a_x=1}^{n/dp}\left(\prod_{j=1}^xa_j^k\right) \]

由于

\[\sum_{a_1=1}^{n}\sum_{a_2=1}^n\dotsb\sum_{a_x=1}^n\left(\prod_{j=1}^xa_j^k\right)=\left(\sum_{i=1}^ni^k\right)^x \]

\[\sum_{d=1}^n\mu^2\left(d\right)d^{kx+1}\sum_{p=1}^{n/d}\mu(p)p^{kx}\left(\sum_{i=1}^{n/dp}i^k\right)^x \]

\(T=dp\),得

\[\sum_{T=1}^{n}T^{kx}\left(\sum_{i=1}^{n/T}i^k\right)^x\sum_{d|T}\mu^2(d)\mu(\frac{T}{d})d \]

\[g(T)=\sum_{d|T}\mu^2(d)\mu(\frac{T}{d})d \]

则原式变为

\[\sum_{T=1}^{n}T^{kx}\left(\sum_{i=1}^{n/T}i^k\right)^xg(T) \]

对于 \(T\in [1,n]\) 的所有 \(g(T)\),我们可以在 \(O(n\log n)\) 的时间预处理出。
最后对于每一组询问,可以在 \(O(\sqrt n)\) 的时间内通过数论分块求出。
\(t\) 为数据组数,则时间复杂度为 \(O(n\log n+t\sqrt n)\)

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
using namespace std;

#define RG register int
#define LL long long

template<typename elemType>
inline void Read(elemType &T){
    elemType X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    T=(w?-X:X);
}

const LL MOD=1000000007LL;
const int maxn=200000;
LL g[maxn+5],h[maxn+5],Mu[maxn+5];
bool not_Prime[maxn+5];
vector<int> Prime;
LL K,X;
int T,n;

LL ExPow(LL b,LL n){
    LL x=1,Power=b%MOD;
    while(n){
        if(n&1) x=x*Power%MOD;
        Power=Power*Power%MOD;
        n>>=1;
    }
    return x;
}

void Get_Mu(int Len){
    Mu[1]=1;
    not_Prime[1]=1;
    int Size=0;
    for(RG i=2;i<=Len;i++){
        if(!not_Prime[i]){
            Prime.push_back(i);
            Mu[i]=-1;++Size;
        }
        for(RG j=0;j<Size;j++){
            int mid=Prime[j]*i;
            if(mid>Len) break;
            not_Prime[mid]=1;
            if(i%Prime[j]==0){
                Mu[i*Prime[j]]=0;
                break;
            }
            Mu[mid]=-Mu[i];
        }
    }
    return;
}

void Init(){
    Get_Mu(maxn);
    for(RG i=1;i<=maxn;++i)
        for(RG j=i;j<=maxn;j+=i)
            g[j]=((g[j]+Mu[i]*Mu[i]*Mu[j/i]*i%MOD)%MOD+MOD)%MOD;
    for(RG i=1;i<=maxn;++i){
        LL temp=ExPow(ExPow(i,K),X);
        g[i]=(g[i-1]+g[i]*temp%MOD)%MOD;
        h[i]=(h[i-1]+ExPow(i,K))%MOD;
    }
    return;
}

LL Solve(){
    LL Res=0;
    for(RG L=1,R;L<=n;L=R+1){
        R=n/(n/L);
        LL temp=ExPow(h[n/L],X);
        Res=((Res+temp*(g[R]-g[L-1])%MOD)%MOD+MOD)%MOD;
    }
    return Res;
}

int main(){
    Read(T);Read(K);Read(X);
    Init();
    while(T--){
        Read(n);
        printf("%lld\n",Solve());
    }
    return 0;
}
posted @ 2020-08-10 11:26  AE酱  阅读(211)  评论(3编辑  收藏  举报