題意
給你n,m,d,k計算下列式子
i1=1∑mi2=1∑mi3=1∑m⋯in=1∑m[gcd(i1,i2,i3,⋯,in)==d](i1i2i3⋯in)k
其中1≤n≤10100000,1≤m,d≤100000,1≤k≤109
思路
先提出一個d
i1=1∑dmi2=1∑dmi3=1∑dm⋯in=1∑dm[gcd(i1,i2,i3,⋯,in)==1]dkn(i1i2i3⋯in)k
dkni1=1∑dmi2=1∑dmi3=1∑dm⋯in=1∑dm[gcd(i1,i2,i3,⋯,in)==1](i1i2i3⋯in)k
再將∑j∣gcd(i1,i2,i3,⋯,in)μ(j)=[gcd(i1,i2,i3,⋯,in)==1]帶入
dkni1=1∑dmi2=1∑dmi3=1∑dm⋯in=1∑dmj∣gcd(i1,i2,i3,⋯,in)∑μ(j)(i1i2i3⋯in)k
原來是枚舉gcd的因子我們可以換成枚舉他的倍數
dknj=1∑dmμ(j)i1=1∑djmi2=1∑djmi3=1∑djm⋯in=1∑djmjkn(i1i2i3⋯in)k
dknj=1∑dmμ(j)jkni1=1∑djmi2=1∑djmi3=1∑djm⋯in=1∑djm(i1i2i3⋯in)k
乘積展開可以爲k次冪的和,只要預處理小於m的k次冪和就可以做了
dknj=1∑dmμ(j)jkn(1k+2k+3k+⋯+(djm)k)n
n比較大,用歐拉降冪
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int mod=59964251;
const int phi=59870352;
int mu[N];
int prime[N];
int vis[N];
int cnt;
long long sum[N];
char str[N];
void init()
{
mu[1]=1;
for(int i=2; i<N; i++)
{
if(!vis[i])
{
prime[cnt++]=i;
mu[i]=-1;
}
for(int j=0; j<cnt&&i*prime[j]<N; j++)
{
vis[prime[j]*i]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
mu[i*prime[j]]=-mu[i];
}
}
}
long long quickmod(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b%2==1)
ans=ans*a%mod;
b=b/2;
a=a*a%mod;
}
return ans;
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
long long m,d,k;
scanf("%s%lld%lld%lld",str,&m,&d,&k);
m/=d;
sum[0]=0;
for(int i=1; i<=m; i++)
sum[i]=(sum[i-1]+quickmod(i,k))%mod;
int len=strlen(str);
int flag=0;
long long n=0;
for(int i=0; i<len; i++)
{
n=n*10+str[i]-'0';
n=n%phi;
}
long long ans=0;
for(int i=1; i<=m; i++)
{
ans=(ans+mu[i]*quickmod(i,k*n%phi+phi)%mod*quickmod(sum[m/i],n+phi)%mod+mod)%mod;
}
ans=ans*quickmod(d,k*n%phi+phi)%mod;
printf("%lld\n",ans);
}
return 0;
}