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;
}
posted @ 2023-02-03 19:06  Aryper  阅读(18)  评论(0编辑  收藏  举报