hdu6588(莫比烏斯反演)

題目:求i=1ngcd(i3,i),n1e21\sum\limits_{i=1}^{n} gcd(\sqrt[3]{i},i),n\leq1e^{21}
本文學習了連接這位大佬的博客,本文僅僅是理解他博客的公式後自己的推公式過程
直接求顯然不可以,推一波公式化簡一下。
前置公式:
(1)莫比烏斯公式:若g(x)=xdf(d)g(x)=\sum\limits_{x|d}f(d),則f(x)=xdμ(dx)g(d)f(x)=\sum\limits_{x|d} \mu(\frac{d}{x})g(d)
(2)歐拉函數與莫比烏斯函數的一個關係式:ϕ(n)=\phi(n)=dnμ(d)nd\sum\limits_{d|n}μ(d)\cdot⌊\frac{n}{d}⌋ ;
(3)i=1ni2=n(n+1)(2n+1)6\sum\limits_{i=1}^{n}i^2=\frac{n(n+1)(2n+1)}{6}
(4)i=1ni=n(n+1)2\sum\limits_{i=1}^{n}i=\frac{n(n+1)}{2}
(5)abbcac若a|b,b|c,則a|c
正式推公式:
i=1ngcd(i3,i)\sum\limits_{i=1}^{n}gcd(\sqrt[3]{i},i)
=i=n33ngcd(n3,i)+a=1n31i=a3(a+1)31gcd(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=lrgcd(a,i)\sum\limits_{i=l}^{r}gcd(a,i)把這部分單獨拿出來求

定義f(l,r,x)=i=lr[gcd(i,a)==x]f(l,r,x)=\sum\limits_{i=l}^{r}[gcd(i,a)==x]
i=lrgcd(a,i)=xaxi=lr[gcd(i,a)==x]=xaxf(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)
ff進行反演一波,構造g(l,r,x)=xdf(l,r,d)=xdf(l,r,d)=xdi=lr[gcd(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)可知ii只要滿足xgcd(i,a)x|gcd(i,a)即爲有效貢獻,所以g(l,r,x)=i=lr[xgcd(i,a)]=rxl1xg(l,r,x)=\sum\limits_{i=l}^{r}[x|gcd(i,a)]=⌊\frac{r}{x}⌋-⌊\frac{l-1}{x}⌋,注意這裏要滿足xax|a
因爲如果xag(l,r,x)=0x不是a的因子的話,g(l,r,x)=0
由公式(1)可知f(l,r,x)=xdμ(dx)g(l,r,d)f(l,r,x)=\sum\limits_{x|d}\mu(\frac{d}{x})g(l,r,d)
因爲如果xag(l,r,x)=0x不是a的因子的話,g(l,r,x)=0
所以f(l,r,x)==xd,daμ(dx)(rdl1d)f(l,r,x)==\sum\limits_{x|d,d|a}\mu(\frac{d}{x})(⌊\frac{r}{d}⌋-⌊\frac{l-1}{d}⌋)
所以i=lrgcd(a,i)=xaxxd,daμ(dx)(rdl1d)=da(rdl1d)xdxμ(dx)=da(rdl1d)ϕ(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)

最後一步就是把xd調xaxd,dax和d的順序調換,本來是先x|a再x|d,d|a轉成先da,xdd|a,再x|d

到這裏就可以Oai=lrgcd(a,i)O(\sqrt{a})求\sum\limits_{i=l}^{r}gcd(a,i)了,所以求解i=n33ngcd(n3,i)\sum\limits_{i=⌊\sqrt[3]{n}⌋^3}^{n}gcd(⌊\sqrt[3]{n}⌋,i)的複雜度爲O(n6)O(\sqrt[6]{n})
對於後一段,直接求複雜度仍然很高,需要繼續化簡a=1n31i=a3(a+1)31gcd(a,i)=a=1n31da((a+1)3da31d)ϕ(d)=d=1n31ϕ(d)i=1n31d(di+1)3ddi31d)=d=1n31i=1n31d(3i2d+3i+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=n31dy=⌊\frac{⌊\sqrt[3]{n}⌋-1}{d}⌋且又(4)(5)得後半段爲
a=1n31i=a3(a+1)31gcd(a,i)=d=1n31ϕ(a)(3dy(y+1)(2y+1)6+3y(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)
yy進行分塊處理,整體複雜度也爲O(n6\sqrt[6]{n}),對ϕ(i)iϕ(i)O(n3)\phi(i)和i\phi(i)前綴和預處理爲O(\sqrt[3]{n})
所以這道題可以在複雜度O(n3)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;
  }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章