HDU 6588 Function 2019杭电多校第一场(莫比乌斯反演)

原题题面

Jerry is fond of functions. He thinks the mystery of the universe is hidden behind the notations, variables and numbers.
Of all functions, he thinks gcd and ⌊ x ⌋ ⌊x⌋ x are the most fascinating, and that something combines gcd with truncation should be even more marvelous.
Therefore, he comes up with a problem:
calculate ∑ i = 1 n g c d ( ⌊ i 3 ⌋ , i )   m o d   998244353 ∑^n_{i=1}gcd(⌊\sqrt[3] i⌋,i)\ mod\ 998244353 i=1ngcd(3i ,i) mod 998244353

输入格式

The input contains several test cases.
The first line contains an integer T ( 1 ≤ T ≤ 11 ) T(1≤T≤11) T(1T11), the number of test cases.
Each of the next T T T lines contains a integer n ( 1 ≤ n ≤ 1 0 21 ) n(1≤n≤10^{21}) n(1n1021), indicating a query.

输出格式

For each test case, output one line containing an integer indicating the corresponding answer.

输入样例

10
64
180
526
267
775
649
749
908
300
255

输出样例

103
327
1069
522
1693
1379
1631
1998
606
492

题面分析

君子报仇一年不晚
对于 ∑ i = 1 N ( ⌊ i 3 ⌋ , i ) \sum_{i=1}^{N}(\lfloor \sqrt[3]{i}\rfloor,i) i=1N(3i ,i)
我们可以根据 ⌊ i 3 ⌋ \lfloor \sqrt[3]{i}\rfloor 3i 的值的不同,把区间拆分开。
我们设 n = ⌊ N 3 ⌋ n=\lfloor\sqrt[3]{N}\rfloor n=3N ,则
∑ i = 1 N ( ⌊ i 3 ⌋ , i ) \sum_{i=1}^{N}(\lfloor \sqrt[3]{i}\rfloor,i) i=1N(3i ,i)
∑ i = 1 n ∑ j = i 3 m i n ( ( i + 1 ) 3 − 1 , N ) g c d ( i , j ) \sum_{i=1}^{n}\sum_{j=i^3}^{min((i+1)^3-1,N)}gcd(i,j) i=1nj=i3min((i+1)31,N)gcd(i,j)
再根据 m i n ( ( i + 1 ) 3 − 1 , N ) min((i+1)^3-1,N) min((i+1)31,N)结果的不同,我们可以得到
∑ i = 1 n − 1 ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) + ∑ i = n 3 N g c d ( n , i ) \sum_{i=1}^{n-1}\sum_{j=i^3}^{(i+1)^3-1}gcd(i,j)+\sum_{i=n^3}^{N}gcd(n,i) i=1n1j=i3(i+1)31gcd(i,j)+i=n3Ngcd(n,i)
式子很大,先考虑后面的 ∑ i = n 3 N g c d ( n , i ) \sum_{i=n^3}^{N}gcd(n,i) i=n3Ngcd(n,i)
∑ i = n 3 N g c d ( n , i ) \sum_{i=n^3}^{N}gcd(n,i) i=n3Ngcd(n,i)
g c d ( n , i ) = d gcd(n,i)=d gcd(n,i)=d,得到
∑ i = n 3 N d [ g c d ( n , i ) = d ] \sum_{i=n^3}^{N}d[gcd(n,i)=d] i=n3Nd[gcd(n,i)=d]
枚举d,可以得到
∑ d ∣ n d ∑ i = n 3 N [ g c d ( n , i ) = d ] \sum_{d|n}d\sum_{i=n^3}^{N}[gcd(n,i)=d] dndi=n3N[gcd(n,i)=d]
∑ d ∣ n d ∑ i = ⌊ n 3 d ⌋ ⌊ N d ⌋ [ g c d ( n d , i ) = 1 ] \sum_{d|n}d\sum_{i=\lfloor \frac{n^3}{d} \rfloor }^{\lfloor{\frac{N}{d}}\rfloor}[gcd(\frac{n}{d},i)=1] dndi=dn3dN[gcd(dn,i)=1]
把后面的 [ g c d ( n d , i ) = 1 ] [gcd(\frac{n}{d},i)=1] [gcd(dn,i)=1]化为 μ ( t ) \mu(t) μ(t),得到
∑ d ∣ n d ∑ i = ⌊ n 3 d ⌋ ⌊ N d ⌋ ∑ t ∣ i , T ∣ n d μ ( t ) \sum_{d|n}d\sum_{i=\lfloor \frac{n^3}{d} \rfloor }^{\lfloor{\frac{N}{d}}\rfloor}\sum_{t|i,T|\frac{n}{d}}{\mu(t)} dndi=dn3dNti,Tdnμ(t)
枚举 t t t,得到
∑ d ∣ n d ∑ t d ∣ n μ ( t ) ∑ i = ⌊ n 3 d t ⌋ ⌊ N d t ⌋ 1 \sum_{d|n}d\sum_{td|n}\mu(t)\sum_{i=\lfloor\frac{n^3}{dt}\rfloor}^{\lfloor \frac{N}{dt}\rfloor}1 dndtdnμ(t)i=dtn3dtN1
此时的复杂度大概是 O ( n 2 ) O(n^2) O(n2),还是太大了,所以还要继续化简。

T = t d ( T ≤ n ) T=td(T\leq n) T=td(Tn),得到
∑ d ∣ n d ∑ T ∣ n μ ( t ) ∑ i = ⌊ n 3 T ⌋ ⌊ N T ⌋ 1 \sum_{d|n}d\sum_{T|n}\mu(t)\sum_{i=\lfloor\frac{n^3}{T}\rfloor}^{\lfloor \frac{N}{T}\rfloor}1 dndTnμ(t)i=Tn3TN1
枚举 T T T,得到
∑ T ∣ n ∑ i = ⌊ n 3 T ⌋ ⌊ N T ⌋ 1 ∗ T t ∗ ∑ T ∣ n μ ( t ) \sum_{T|n}\sum_{i=\lfloor\frac{n^3}{T}\rfloor}^{\lfloor \frac{N}{T}\rfloor}1*\frac{T}{t}*\sum_{T|n}\mu(t) Tni=Tn3TN1tTTnμ(t)
∑ T ∣ n ∑ i = ⌊ n 3 T ⌋ ⌊ N T ⌋ 1 ∗ ∑ T ∣ n μ ( t ) ∗ T t \sum_{T|n}\sum_{i=\lfloor\frac{n^3}{T}\rfloor}^{\lfloor \frac{N}{T}\rfloor}1*\sum_{T|n}\mu(t)*\frac{T}{t} Tni=Tn3TN1Tnμ(t)tT
其中, ∑ T ∣ n μ ( t ) ∗ T t = μ ( T ) ∗ i d ( T ) = φ ( T ) \sum_{T|n}\mu(t)*\frac{T}{t}=\mu(T)*id(T)=\varphi(T) Tnμ(t)tT=μ(T)id(T)=φ(T)(狄里克莱卷积)
故答案为
∑ T ∣ n ∑ i = ⌊ n 3 T ⌋ ⌊ N T ⌋ 1 ∗ φ ( T ) \sum_{T|n}\sum_{i=\lfloor\frac{n^3}{T}\rfloor}^{\lfloor \frac{N}{T}\rfloor}1*\varphi(T) Tni=Tn3TN1φ(T)

∑ T ∣ n ∗ [ ⌊ N T ⌋ − ⌊ n 3 T ⌋ + 1 ] ∗ φ ( T ) \sum_{T|n}*[\lfloor \frac{N}{T}\rfloor-\lfloor\frac{n^3}{T}\rfloor+1]*\varphi(T) Tn[TNTn3+1]φ(T)
其中, φ \varphi φ可以 O ( n ) O(n) O(n)线性筛出,枚举 T T T需要 O ( n ) O(\sqrt{n}) O(n )

再来计算前面的 ∑ i = 1 n − 1 ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) \sum_{i=1}^{n-1}\sum_{j=i^3}^{(i+1)^3-1}gcd(i,j) i=1n1j=i3(i+1)31gcd(i,j)
n − 1 n-1 n1在式子里挺不便于计算,我们转而去算 ∑ i = 1 n ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) \sum_{i=1}^{n}\sum_{j=i^3}^{(i+1)^3-1}gcd(i,j) i=1nj=i3(i+1)31gcd(i,j)
g c d ( i , j ) = d gcd(i,j)=d gcd(i,j)=d,得到
∑ i = 1 n ∑ j = i 3 ( i + 1 ) 3 − 1 d [ g c d ( i , j ) = d ] \sum_{i=1}^{n}\sum_{j=i^3}^{(i+1)^3-1}d[gcd(i,j)=d] i=1nj=i3(i+1)31d[gcd(i,j)=d]
枚举 d d d得到
∑ d = 1 n d ∑ i = 1 n ∑ j = i 3 ( i + 1 ) 3 − 1 [ g c d ( i , j ) = d ] \sum_{d=1}^{n}d\sum_{i=1}^{n}\sum_{j=i^3}^{(i+1)^3-1}[gcd(i,j)=d] d=1ndi=1nj=i3(i+1)31[gcd(i,j)=d]
i , j i,j i,j同除以 d d d得到
∑ d = 1 n d ∑ i = 1 ⌊ n d ⌋ ∑ j = ⌊ i 3 d ⌋ ⌊ ( i d + 1 ) 3 − 1 d ⌋ [ g c d ( i , j ) = 1 ] \sum_{d=1}^{n}d\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=\lfloor \frac{i^3}{d}\rfloor}^{\lfloor\frac{(id+1)^3-1}{d}\rfloor}[gcd(i,j)=1] d=1ndi=1dnj=di3d(id+1)31[gcd(i,j)=1]
(注意这里 j j j的上界不是 ⌊ ( i + 1 ) 3 − 1 d ⌋ {\lfloor\frac{(i+1)^3-1}{d}\rfloor} d(i+1)31,而是 ⌊ ( i d + 1 ) 3 − 1 d ⌋ {\lfloor\frac{(id+1)^3-1}{d}\rfloor} d(id+1)31,因为 i i i的值变化了)
[ g c d ( i , j ) = 1 ] [gcd(i,j)=1] [gcd(i,j)=1]变为 μ ( t ) \mu(t) μ(t),得到
∑ d = 1 n d ∑ i = 1 ⌊ n d ⌋ ∑ j = ⌊ i 3 d ⌋ ⌊ ( i d + 1 ) 3 − 1 d ⌋ ∑ t ∣ i , t ∣ j μ ( t ) \sum_{d=1}^{n}d\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=\lfloor \frac{i^3}{d}\rfloor}^{\lfloor\frac{(id+1)^3-1}{d}\rfloor}\sum_{t|i,t|j}\mu(t) d=1ndi=1dnj=di3d(id+1)31ti,tjμ(t)
枚举 t t t,得到
∑ d = 1 n d ∑ t = 1 ⌊ n d ⌋ μ ( t ) ∑ i = 1 ⌊ n t d ⌋ ∑ j = ⌊ i 3 d t ⌋ ⌊ ( i d t + 1 ) 3 − 1 d t ⌋ 1 \sum_{d=1}^{n}d\sum_{t=1}^{\lfloor\frac{n}{d}\rfloor}\mu(t)\sum_{i=1}^{\lfloor\frac{n}{td}\rfloor}\sum_{j=\lfloor \frac{i^3}{dt}\rfloor}^{\lfloor\frac{(idt+1)^3-1}{dt}\rfloor}1 d=1ndt=1dnμ(t)i=1tdnj=dti3dt(idt+1)311
(同样也要注意这里的 j j j的上界)
T = t d T=td T=td
∑ d = 1 n d ∑ t = 1 ⌊ n d ⌋ μ ( t ) ∑ i = 1 ⌊ n T ⌋ ∑ j = ⌊ i 3 T ⌋ ⌊ ( i T + 1 ) 3 − 1 T ⌋ 1 \sum_{d=1}^{n}d\sum_{t=1}^{\lfloor\frac{n}{d}\rfloor}\mu(t)\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=\lfloor \frac{i^3}{T}\rfloor}^{\lfloor\frac{(iT+1)^3-1}{T}\rfloor}1 d=1ndt=1dnμ(t)i=1Tnj=Ti3T(iT+1)311
枚举 T T T,得
∑ T = 1 n T t ∗ ( ∑ i = 1 ⌊ n T ⌋ ∑ j = ⌊ i 3 T ⌋ ⌊ ( i T + 1 ) 3 − 1 T ⌋ 1 ) ∑ t ∣ T μ ( t ) \sum_{T=1}^{n}\frac{T}{t}*(\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=\lfloor \frac{i^3}{T}\rfloor}^{\lfloor\frac{(iT+1)^3-1}{T}\rfloor}1)\sum_{t|T}{\mu(t)} T=1ntT(i=1Tnj=Ti3T(iT+1)311)tTμ(t)
∑ T = 1 n ( ∑ i = 1 ⌊ n T ⌋ ∑ j = ⌊ i 3 T ⌋ ⌊ ( i T + 1 ) 3 − 1 T ⌋ 1 ) ∑ t ∣ T μ ( t ) T t \sum_{T=1}^{n}(\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=\lfloor \frac{i^3}{T}\rfloor}^{\lfloor\frac{(iT+1)^3-1}{T}\rfloor}1)\sum_{t|T}{\mu(t)\frac{T}{t}} T=1n(i=1Tnj=Ti3T(iT+1)311)tTμ(t)tT
同理 μ ∗ i d = φ \mu*id=\varphi μid=φ
∑ T = 1 n ( ∑ i = 1 ⌊ n T ⌋ ∑ j = ⌊ i 3 T ⌋ ⌊ ( i T + 1 ) 3 − 1 T ⌋ 1 ) φ ( T ) \sum_{T=1}^{n}(\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=\lfloor \frac{i^3}{T}\rfloor}^{\lfloor\frac{(iT+1)^3-1}{T}\rfloor}1)\varphi(T) T=1n(i=1Tnj=Ti3T(iT+1)311)φ(T)
对于中间的 ( ∑ i = 1 ⌊ n T ⌋ ∑ j = ⌊ i 3 T ⌋ ⌊ ( i T + 1 ) 3 − 1 T ⌋ 1 ) (\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=\lfloor \frac{i^3}{T}\rfloor}^{\lfloor\frac{(iT+1)^3-1}{T}\rfloor}1) (i=1Tnj=Ti3T(iT+1)311),其实就是个计数,稍加化简得到= 3 T ∑ i = 1 ⌊ n T ⌋ i 2 + 3 ∑ i = 1 ⌊ n T ⌋ i + ∑ i = 1 ⌊ n T ⌋ 1 3T\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}i^2+3\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}i+\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}1 3Ti=1Tni2+3i=1Tni+i=1Tn1,可以 O ( n ) O(n) O(n)或者 O ( n ) O(\sqrt n) O(n )预处理。
至此,总复杂度为 O ( N 3 ) O(\sqrt[3]N) O(3N )

AC代码(2995ms)

内存给的比较死,数组可以尽量开int还不是long long(笔者是卡着内存过的)
因为 1 0 21 10^{21} 1021是超出long long 范围,故采用int128。

#include 
using namespace std;
const long long maxn=1e7;
const long long mod=998244353;
long long phi[maxn+10];
long long sum1[maxn+10];//i^2前缀和
long long sum2[maxn+10];//i前缀和
int num=0;//质数个数
bool vis[maxn+10];
long long prime[maxn+10];
__int128 N;
__int128 n3;//n*n*n
long long n;//sqrt3(N)
inline void read(__int128 &X)//int128读入
{
    X=0;
    int w=0;
    char ch=0;
    while(!isdigit(ch))
    {
        w|=ch=='-';
        ch=getchar();
    }
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48), ch=getchar();
    if (w) X=-X;
}
inline void print(__int128 x)//int128读出
{
    if (!x) return;
    if (x<0) putchar('-'), x=-x;
    print(x/10);
    putchar(x%10+'0');
}
void init()//处理phi和两个前缀和
{
    phi[1]=sum1[1]=sum2[1]=1;
    for(long long  i=2; i<=maxn; i++)
    {
        sum1[i]=(sum1[i-1]+i)%mod;
        sum2[i]=(sum2[i-1]+i*i%mod)%mod;
        if (!vis[i]) prime[++num]=i, phi[i]=i-1;
        for(int j=1; j<=maxn && i*prime[j]<=maxn; j++)
        {
            vis[i*prime[j]]=1;
            if (i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
}
long long f2()//后半部分
{
    long long ans=0;
    for(long long T=1; T*T<=n; T++)//计算T和n/T
    {
        if (n%T==0)
        {
            ans=(ans+phi[T]*((N/T)%mod-(n3/T)%mod+1+mod)%mod)%mod;
            if (T*T!=n)//T!=sqrt(n)
                ans=(ans+phi[n/T]*((N/(n/T))%mod-(n3/(n/T))%mod+1+mod)%mod)%mod;
        }
    }
    return ans;
}
long long f3(long long T)//前半部分的中间部分
{
    return (3ll*T%mod*sum2[n/T]%mod+3ll*sum1[n/T]%mod+n/T%mod)%mod;
}
void solve()
{
    init();
    int t;
    scanf("%d", &t);
    while(t--)
    {
        read(N);
        n=(long long) (pow(N, (long double) 1.0/3.0));
        n3=(__int128) n*n*n;
        long long ans=f2();
        n--;
        for(long long T=1;T<=n;T++)
        {
            ans=(ans+phi[T]*f3(T)%mod)%mod;
        }
        printf("%lld\n",ans);
    }
}
int main()
{
//    ios_base::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long long test_index_for_debug=1;
    char acm_local_for_debug;
    while(cin>>acm_local_for_debug)
    {
        cin.putback(acm_local_for_debug);
        if (test_index_for_debug>100)
        {
            throw runtime_error("Check the stdin!!!");
        }
        auto start_clock_for_debug=clock();
        solve();
        auto end_clock_for_debug=clock();
        cout<<"\nTest "<<test_index_for_debug<<" successful"<<endl;
        cerr<<"Test "<<test_index_for_debug++<<" Run Time: "
            <<double(end_clock_for_debug-start_clock_for_debug)/CLOCKS_PER_SEC<<"s"<<endl;
        cout<<"--------------------------------------------------"<<endl;
    }
#else
    solve();
#endif
    return 0;
}

DrGilbert 2020.8.7

你可能感兴趣的:(数论)