hdu6588(莫比乌斯反演)

题目:求 i = 1 n g c d ( i 3 , i ) , n 1 e 21 \sum\limits_{i=1}^{n} gcd(\sqrt[3]{i},i),n\leq1e^{21}
本文学习了连接这位大佬的博客,本文仅仅是理解他博客的公式后自己的推公式过程
直接求显然不可以,推一波公式化简一下。
前置公式:
(1)莫比乌斯公式:若 g ( x ) = x d f ( d ) g(x)=\sum\limits_{x|d}f(d) ,则 f ( x ) = x d μ ( d x ) g ( d ) f(x)=\sum\limits_{x|d} \mu(\frac{d}{x})g(d)
(2)欧拉函数与莫比乌斯函数的一个关系式: ϕ ( n ) = \phi(n)= d n μ ( d ) n d \sum\limits_{d|n}μ(d)\cdot⌊\frac{n}{d}⌋ ;
(3) i = 1 n i 2 = n ( n + 1 ) ( 2 n + 1 ) 6 \sum\limits_{i=1}^{n}i^2=\frac{n(n+1)(2n+1)}{6}
(4) i = 1 n i = n ( n + 1 ) 2 \sum\limits_{i=1}^{n}i=\frac{n(n+1)}{2}
(5) a b b c a c 若a|b,b|c,则a|c
正式推公式:
i = 1 n g c d ( i 3 , i ) \sum\limits_{i=1}^{n}gcd(\sqrt[3]{i},i)
= i = n 3 3 n g c d ( n 3 , i ) + a = 1 n 3 1 i = a 3 ( a + 1 ) 3 1 g c d ( a , i ) =\sum\limits_{i=⌊\sqrt[3]{n}⌋^3}^{n}gcd(⌊\sqrt[3]{n}⌋,i)+\sum\limits_{a=1}^{⌊\sqrt[3]{n}⌋-1}\sum\limits_{i=a^3}^{(a+1)^3-1}gcd(a,i)
我们看到求解的问题被分为两部分,但前后两部分都有求 i = l r g c d ( a , i ) \sum\limits_{i=l}^{r}gcd(a,i) 把这部分单独拿出来求

定义 f ( l , r , x ) = i = l r [ g c d ( i , a ) = = x ] f(l,r,x)=\sum\limits_{i=l}^{r}[gcd(i,a)==x]
i = l r g c d ( a , i ) = x a x i = l r [ g c d ( i , a ) = = x ] = x a x f ( l , r , x ) \sum\limits_{i=l}^{r}gcd(a,i)=\sum\limits_{x|a}x\sum\limits_{i=l}^{r}[gcd(i,a)==x]=\sum\limits_{x|a}xf(l,r,x)
f f 进行反演一波,构造 g ( l , r , x ) = x d f ( l , r , d ) = x d f ( l , r , d ) = x d i = l r [ g c d ( i , a ) = = d ] g(l,r,x)=\sum\limits_{x|d}f(l,r,d)=\sum\limits_{x|d}f(l,r,d)=\sum\limits_{x|d}\sum\limits_{i=l}^{r}[gcd(i,a)==d]
由公式(5)可知 i i 只要满足 x g c d ( i , a ) x|gcd(i,a) 即为有效贡献,所以 g ( l , r , x ) = i = l r [ x g c d ( i , a ) ] = r x l 1 x g(l,r,x)=\sum\limits_{i=l}^{r}[x|gcd(i,a)]=⌊\frac{r}{x}⌋-⌊\frac{l-1}{x}⌋ ,注意这里要满足 x a x|a
因为如果 x a g ( l , r , x ) = 0 x不是a的因子的话,g(l,r,x)=0
由公式(1)可知 f ( l , r , x ) = x d μ ( d x ) g ( l , r , d ) f(l,r,x)=\sum\limits_{x|d}\mu(\frac{d}{x})g(l,r,d)
因为如果 x a g ( l , r , x ) = 0 x不是a的因子的话,g(l,r,x)=0
所以 f ( l , r , x ) = = x d , d a μ ( d x ) ( r d l 1 d ) f(l,r,x)==\sum\limits_{x|d,d|a}\mu(\frac{d}{x})(⌊\frac{r}{d}⌋-⌊\frac{l-1}{d}⌋)
所以 i = l r g c d ( a , i ) = x a x x d , d a μ ( d x ) ( r d l 1 d ) = d a ( r d l 1 d ) x d x μ ( d x ) = d a ( r d l 1 d ) ϕ ( d ) \sum\limits_{i=l}^{r}gcd(a,i)=\sum\limits_{x|a}x\sum\limits_{x|d,d|a}\mu(\frac{d}{x})(⌊\frac{r}{d}⌋-⌊\frac{l-1}{d}⌋)=\sum\limits_{d|a}(⌊\frac{r}{d}⌋-⌊\frac{l-1}{d}⌋)\sum\limits_{x|d}x\mu(\frac{d}{x})=\sum\limits_{d|a}(⌊\frac{r}{d}⌋-⌊\frac{l-1}{d}⌋)\phi(d)

最后一步就是把 x d x a x d , d a x和d的顺序调换,本来是先x|a再x|d,d|a 转成先 d a , x d d|a,再x|d

到这里就可以 O a i = l r g c d ( a , i ) O(\sqrt{a})求\sum\limits_{i=l}^{r}gcd(a,i) 了,所以求解 i = n 3 3 n g c d ( n 3 , i ) \sum\limits_{i=⌊\sqrt[3]{n}⌋^3}^{n}gcd(⌊\sqrt[3]{n}⌋,i) 的复杂度为 O ( n 6 ) O(\sqrt[6]{n})
对于后一段,直接求复杂度仍然很高,需要继续化简 a = 1 n 3 1 i = a 3 ( a + 1 ) 3 1 g c d ( a , i ) = a = 1 n 3 1 d a ( ( a + 1 ) 3 d a 3 1 d ) ϕ ( d ) = d = 1 n 3 1 ϕ ( d ) i = 1 n 3 1 d ( d i + 1 ) 3 d d i 3 1 d ) = d = 1 n 3 1 i = 1 n 3 1 d ( 3 i 2 d + 3 i + 1 ) ϕ ( d ) \sum\limits_{a=1}^{⌊\sqrt[3]{n}⌋-1}\sum\limits_{i=a^3}^{(a+1)^3-1}gcd(a,i)=\sum\limits_{a=1}^{⌊\sqrt[3]{n}⌋-1}\sum\limits_{d|a}(⌊\frac{(a+1)^3}{d}⌋-⌊\frac{a^3-1}{d}⌋)\phi(d)=\sum\limits_{d=1}^{⌊\sqrt[3]{n}⌋-1}\phi(d)\sum\limits_{i=1}^{⌊\frac{⌊\sqrt[3]{n}⌋-1}{d}⌋}⌊\frac{(di+1)^3}{d}⌋-⌊\frac{di^3-1}{d}⌋)= \sum\limits_{d=1}^{⌊\sqrt[3]{n}⌋-1}\sum\limits_{i=1}^{⌊\frac{⌊\sqrt[3]{n}⌋-1}{d}⌋}(3i^2d+3i+1)\phi(d)
y = n 3 1 d y=⌊\frac{⌊\sqrt[3]{n}⌋-1}{d}⌋ 且又(4)(5)得后半段为
a = 1 n 3 1 i = a 3 ( a + 1 ) 3 1 g c d ( a , i ) = d = 1 n 3 1 ϕ ( a ) ( 3 d y ( y + 1 ) ( 2 y + 1 ) 6 + 3 y ( y + 1 ) 2 + y ) \sum\limits_{a=1}^{⌊\sqrt[3]{n}⌋-1}\sum\limits_{i=a^3}^{(a+1)^3-1}gcd(a,i)=\sum\limits_{d=1}^{⌊\sqrt[3]{n}⌋-1}\phi(a)(3*d*\frac{y(y+1)(2y+1)}{6}+3\frac{y(y+1)}{2}+y)
y y 进行分块处理,整体复杂度也为O( n 6 \sqrt[6]{n} ),对 ϕ ( i ) i ϕ ( i ) O ( n 3 ) \phi(i)和i\phi(i)前缀和预处理为O(\sqrt[3]{n})
所以这道题可以在复杂度 O ( n 3 ) O(\sqrt[3]{n}) 下完成。
代码因为找不到错误,对拍对着对着跟原博主的代码越来越像。
ac代码:

#include<bits/stdc++.h>
#define db double
#define ui unsigned int
#define ll long long
#define ull unsiged ll
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l)for(int i=r;i>=l;i--)
#define file(x) freopen(#x".in","w",stdout);
#define bug(x) cerr<<#x<<": "<<x<<endl
typedef __int128 int128;
using namespace std;
const int MX = 1e7 + 7;
const int mod=998244353;
ll modulo(ll num, ll MOD = mod) { return ((num%MOD) + MOD) % MOD; }
ll power(ll b, ll e, ll MOD = mod) { ll ans = 1; while (e) { if (e % 2) ans = (ans*b) % MOD; b = (b*b) % MOD; e /= 2; } return ans; }
ll inv(ll num, ll MOD = mod) { return power(modulo(num), MOD - 2, MOD); }
ll gcd(ll a, ll b) { return ((b == 0) ? a : gcd(b, a%b)); }
ll phi[MX];
ll pri[MX],inv2,inv6,iphi[MX],phisum[MX];
bool isp[MX];
int tmp=0;
struct Istream {
    template <class T>
    Istream &operator >>(T &x) {
        static char ch;static bool neg;
        for(ch=neg=0;ch<'0' || '9'<ch;neg|=ch=='-',ch=getchar());
        for(x=0;'0'<=ch && ch<='9';(x*=10)+=ch-'0',ch=getchar());
        x=neg?-x:x;
        return *this;
    }
}fin;
struct Ostream {
    template <class T>
    Ostream &operator <<(T x) {
        x<0 && (putchar('-'),x=-x);
        static char stack[233];static int top;
        for(top=0;x;stack[++top]=x%10+'0',x/=10);
        for(top==0 && (stack[top=1]='0');top;putchar(stack[top--]));
        return *this;
    }
    Ostream &operator <<(char ch) {
        putchar(ch);
        return *this;
    }
}fout;
void pre_phi()
{
  isp[0]=isp[1]=false;
  phi[1]=1;
  for(int i=2;i<MX;i++)
  {
    if(!isp[i])
    {
      pri[++tmp]=i;
      phi[i]=i-1;
    }
    for(ll j=1;i*pri[j]<MX&&j<=tmp;j++)
    {
      int ans=i*pri[j];
      isp[ans]=true;
      if(i%pri[j])
      {
        phi[ans]=phi[i]*(pri[j]-1);
      }
      else {
        phi[ans]=phi[i]*pri[j];
        break;
      }
    }
  }
  phisum[1]=1,iphi[1]=1;
  for(int i=2;i<MX;i++)
  {
    iphi[i]=(iphi[i-1]+1ll*i*phi[i]%mod)%mod;
    phisum[i]=(phisum[i-1]+phi[i])%mod;
  }
}
int128 get_n3(int128 n)
{
  int128  l=0,r=1e8,res=1,mid;
  while(l<=r)
  {
      mid=(l+r)/2;
    if(int128(mid*mid*mid)<=n)res=mid,l=mid+1;
    else r=mid-1;
  }
  return res;
}
int main()
{
	inv2=inv(2),inv6=inv(6);
	int t;
	pre_phi();
	fin>>t;
	while(t--){
	int128 n;
	fin>>n;
	ll ans=0;
	int128 n3=get_n3(n);
	int128 m=n3*n3*n3;
	for(ll i=1;i*i<=n3;i++)
  {
    if(n3%i==0)
    {
      ans=ans+phi[i]*(n/i-(m-1)/i)%mod;
      ll t=n3/i;
      if(i*i!=n3)
        ans+=phi[t]*(n/t-(m-1)/t)%mod;
      ans=ans%mod;
    }
  }
  n3--;
  ll j,res;
  for(ll i=1;i<=n3;i=j+1)
  {
    res=n3/i;
    j=n3/res;
    ans=ans+3*(iphi[j]-iphi[i-1]+mod)%mod*res%mod*(res+1)%mod*(2*res+1)%mod*inv6%mod;
    ans=ans+(phisum[j]-phisum[i-1]+mod)%mod*(3*res*(res+1)%mod*inv2%mod+res)%mod;
    ans=ans%mod;
  }
  fout<<ans<<'\n';
  //cout<<ans<<endl;
  }
}



发布了109 篇原创文章 · 获赞 35 · 访问量 6011

猜你喜欢

转载自blog.csdn.net/weixin_43965698/article/details/103606453