P6222 「P6156 简单题」加强版
「P6156 简单题」加强版
题意即求:
\[\sum _ { i= 1} ^ {n} \sum _ {j=1} ^ {n} (i+j) ^ {K} \gcd (i, j) \mu ^ 2 (\gcd ( i , j )) \pmod {2^{32}}
\]
其中 \(T\le 10 ^ 4\),\(n\le 10^7\),\(K < 2^{31}\)。
然后这个题加强在于预处理必须线性。
开始推导:
\[\begin{aligned}
&
\sum _ { i= 1} ^ {n} \sum _ {j=1} ^ {n} (i+j) ^ {K} \gcd (i, j) \mu ^ 2 (\gcd ( i , j ))
\\
= &
\sum _ {d = 1} \sum _ { i= 1} ^ {n} \sum _ {j=1} ^ {n} (i+j) ^ {K} \left[ \gcd(i,j) = d \right]d \mu ^ 2 (d)
\\
= &
\sum _ {d = 1} \sum _ { i= 1} ^ {\left\lfloor n/d\right\rfloor} \sum _ {j=1} ^ {\left\lfloor n/d\right\rfloor} d^ {K} (i+j) ^ {K} \left[ \gcd(i,j) = 1 \right]d \mu ^ 2 (d)
\\
= &
\sum _ {d = 1} d ^ {K+1} \mu ^ 2 (d)\sum _ { i= 1} ^ {\left\lfloor n/d\right\rfloor} \sum _ {j=1} ^ {\left\lfloor n/d\right\rfloor} (i+j) ^ {K} \sum _ {k\mid i, k \mid j} \mu (k)
\\
= &
\sum _ {d = 1} d ^ {K+1} \mu ^ 2 (d) \sum _ { k = 1 } \mu (k) k ^ {K} \sum _ { i= 1} ^ {\left\lfloor n/kd\right\rfloor} \sum _ {j=1} ^ {\left\lfloor n/kd\right\rfloor} (i+j) ^ {K}
\\
= &
\sum _ { T = 1 }\sum _ {d \mid T} d ^ {K+1} \mu ^ 2 (d) \mu \left(\dfrac{T}{d}\right) \left(\dfrac{T}{d}\right) ^ {K}\sum _ { i= 1} ^ {\left\lfloor n/T\right\rfloor} \sum _ {j=1} ^ {\left\lfloor n/T\right\rfloor} (i+j) ^ {K}
\\
= &
\sum _ { T = 1 }\left(T ^ {K} \sum _ {d \mid T} d \mu ^ 2 (d) \mu \left(\dfrac{T}{d}\right) \right)
\sum _ { i= 1} ^ {\left\lfloor n/T\right\rfloor} \sum _ {j=1} ^ {\left\lfloor n/T\right\rfloor} (i+j) ^ {K}
\end{aligned}
\]
括号内的东西,去掉 \(T ^ {K}\),剩下是个积性函数,可以线性筛(主要因为其特殊结构,分类讨论一下即可)。
后面的东西是可以先预处理出:
\[f(n) = \sum _ { i = 1 } ^ {n} \sum _ { j = 1 } ^ {n} (i+j) ^ K
\]
这是容易的:
\[f(n) = \sum _ { i = 1 } ^ {n} \sum _ { j = 1 } ^ {n} (i+j) ^ K = \sum _ { i = 1} ^ {n-1} \sum _ { j = 1 } ^ {n-1} (i+j) ^ {K} + 2\sum _ { i = n + 1} ^ {2n-1} i ^ {K} + (2n)^ {K}
\]
于是预处理线性,剩下的整除分块即可。
时间复杂度 \(O(n+T\sqrt{n})\)。
本题要卡点常。
代码:
#include<iostream>
#include<cstdio>
#define ll unsigned int
using namespace std;
namespace Ehnaev{
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<48||ch>57) {ch=getchar();}
while(ch>=48&&ch<=57) {ret=(ret<<3)+(ret<<1)+ch-48;ch=getchar();}
return ret*f;
}
inline void write(ll x) {
static char buf[22];static long long len=-1;
do{buf[++len]=x%10+48;x/=10;}while(x);
while(len>=0) putchar(buf[len--]);
}
}using Ehnaev::read;using Ehnaev::write;
inline void writeln(ll x) {write(x);putchar(10);}
const ll N=1e7;
inline ll Qpow(ll b,ll p) {
ll r=1;while(p) {if(p&1) r=r*b;b=b*b;p>>=1;}return r;
}
ll T,nn,K,n,cnt,ans;
ll prime[N*2+5];
ll idk[N*2+5],s2[N+5],f[N+5];
bool ff[N*2+5];
inline void Init() {
ff[1]=1;idk[1]=1;f[1]=1;
for(ll i=2;i<=nn*2;i++) {
if(!ff[i]) {
prime[++cnt]=i;idk[i]=Qpow(i,K);
if(i<=nn) f[i]=i-1;
}
for(ll j=1;j<=cnt&&i*prime[j]<=nn*2;j++) {
idk[i*prime[j]]=idk[i]*idk[prime[j]];
ff[i*prime[j]]=1;
if(i%prime[j]==0) {
if(i*prime[j]>nn) break;
if((i/prime[j])%prime[j]==0) {f[i*prime[j]]=0;}
else {
f[i*prime[j]]=f[i/prime[j]]*(-prime[j]);
}
break;
}
f[i*prime[j]]=f[i]*f[prime[j]];
}
}
for(ll i=1;i<=nn*2;i++) {idk[i]=idk[i-1]+idk[i];}
for(ll i=1;i<=nn;i++) {
s2[i]=s2[i-1]+2*(idk[2*i-1]-idk[i])+idk[2*i]-idk[2*i-1];
}
for(ll i=1;i<=nn;i++) {f[i]=f[i]*(idk[i]-idk[i-1]);}
for(ll i=1;i<=nn;i++) {f[i]=f[i-1]+f[i];}
}
int main() {
T=read();nn=read();K=read();
Init();
while(T--) {
n=read();ans=0;
for(ll i=1,j;i<=n;i=j+1) {
j=n/(n/i);
ans=ans+(f[j]-f[i-1])*s2[n/i];
}
writeln(ans);
}
return 0;
}