Problem: Coprime Arrays (Mobius inversion & differential)

topic

Portal

Thinking

Luo Gu meaning of the questions a little problem, would have a direct translation of the English title face

For number theory, should deformation violence

\(b_i=\sum_{a_1=1}^{i}\sum_{a_2=1}^{i}\dots\sum_{a_k=1}^{i}[gcd(a_1,a_2\cdots,a_k)==1]\)

We see that a part of gcd back, it is easy to think of \ (\ mu \)

\(b_i=\sum_{a_1=1}^{i}\sum_{a_2=1}^{i}\dots\sum_{a_k=1}^{i}\sum_{d|gcd(a_1,a_2\cdots,a_k)}\mu(d)\)

According to routine

\(b_i=\sum_{d=1}^{i}(\mu(d)*\lfloor\frac{i}{d}\rfloor^k)\)

After divisible routines of block

You can then \ (O (\ sqrt n * log_n) \) time processing a single \ (b_i \)

then?

Then overtime

This is not nonsense?

We think about how to optimize

First ^ certainly can not be brought into the equation, or will be very troublesome

But we seemed to have to know each \ (b_i \) ,

We consider two adjacent differences

\(b_i-b_{i-1}=\sum_{d=1}^{i}(\mu(d)*\lfloor\frac{i}{d}\rfloor^k)-\sum_{d=1}^{i-1}(\mu(d)*\lfloor\frac{i-1}{d}\rfloor^k)\)

Then we were surprised to find that, then for \ (d \) case identified

Many of the formulas are cancel each other out,

So we only need to calculate those points can produce changes

It is easy to launch, only if \ (d | i \) , the former will be larger than the latter 1

\(b_i-b_{i-1}=\sum_{d|i}(\mu(d)*(\lfloor\frac{i}{d}\rfloor^k-(\lfloor\frac{i}{d}\rfloor-1)^k)\)

after that?

After the k-th power of memory

Violence on the van thing

The total time complexity \ (O (n * logn * logn) \)

Code

#include<iostream>
using namespace std;
const long long mod=1e9+7;
int n,k;
int mu[2000005];
int pri[2000005];
int lenp;
bool vis[2000005];
long long b[2000005];
long long ans;
long long mem[2000005];
void oular()
{
    mu[1]=1;
    for(int i=2;i<=2000000;i++)
    {
        if(!vis[i])
        {
            pri[++lenp]=i;
            mu[i]=-1;
        }
        for(int j=1;pri[j]*i<=2000000&&j<=lenp;j++)
        {
            if(i%pri[j]==0)
            {
                mu[i*pri[j]]=0;
                vis[i*pri[j]]=1;
                break;
            }
            mu[i*pri[j]]=-mu[i];
            vis[i*pri[j]]=1;
        }
    }
}
long long qkpow(long long a,int b)
{
    if(b==n&&mem[a]!=0)
        return mem[a];
    if(b==0)
        return 1;
    if(b==1)
        return a;
    long long t=qkpow(a,b/2);
    t=t*t%mod;
    if(b%2==1)
        t=t*a%mod;
    if(b==n)
        mem[a]=t;
    return t;
}
int main()
{
    cin>>n>>k;
    oular();
    for(int i=1;i<=k;i++)
        for(int j=1;j*i<=k;j++)
            b[i*j]=(b[i*j]+(1ll*(mu[i]+mod)%mod)*(qkpow(j,n)-qkpow(j-1,n)+mod)%mod)%mod;
    for(int i=2;i<=k;i++)
    {
        b[i]=(b[i]+b[i-1])%mod;
        ans=(ans+(b[i]^i))%mod;
    }
    cout<<ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/loney-s/p/12593746.html