LG4213 [template] Du teach sieve (Sum)

P4213 [template] Du teach sieve (Sum)

Title Description

Given a positive integer $ N (N \ le2 ^ {31} -1) $

begging

$$ans_1=\sum_{i=1}^n\varphi(i)$$

$$ans_2=\sum_{i=1}^n \mu(i)$$

Input and output formats

Input formats:

T + 1 total row number of the first data group behavior T (T <= 10) of 2 ~ T + 1 lines each a non-negative integer N, represents a set of query

Output formats:

A total of T lines of two spaces separated by a number of ans1, ans2

Sample input and output

Input Sample # 1: Copy
6
1
2
8
13
30
2333
Output Sample # 1: Copy
1 1
2 0
22 -2
58 -3
278 -3
1655470 2

AcFirmament solution to a problem of

Du teach screen template

Du teach screen is used to dry clams it?

It can quadrature function of the prefix and a non-linear time.

Pre-knowledge

Multiplicative function

Multiplicative function: For any integers coprime $ a, b $ there is $ f (ab) = f (a) f (b) $ called $ f (x) $ arithmetical functions.

Completely multiplicative function: for any integer $ a, b $ there is $ f (ab) = f (a) f (b) $ arithmetical functions.

  • Common multiplicative function: $ \ varphi, \ mu, \ sigma, d $
  • Common totally multiplicative function: $ \ epsilon, I, id $

Here special explain the $ \ epsilon, I, id $, respectively, what is the meaning: $ \ epsilon (n) = [n = 1], I (n) = 1, id (n) = n $

Dirichlet convolution

Set $ ​​f, g $ are two arithmetic functions, Dirichlet thereof Convolution is: $ (f * g) (n) = \ sum \ limits _ {d | n} f (d) g (\ frac {n} {d}) $

Properties: commutative, associative

Identity element: $ \ epsilon $ (ie $ f * \ epsilon = f $)

Some properties of Dirichlet convolution binding obtained:

  1. $ \ Mu * I = \ epsilon $
  2. $\varphi * I = id$
  3. $\mu * id = \varphi$

Mobius inversion

若 $$g(n) = \sum\limits_{d|n}f(d)$$

则 $$f(n)=\sum\limits_{d|n}\mu(d)g(\frac{n}{d})$$

Proof: Here we need to use nature previously mentioned: $ \ mu * I = \ epsilon $

Given conditions equivalent to $ g = f * I $

So $ g * \ mu = f * I * \ mu = f * \ epsilon = f $ ie $ g * \ mu = f $ that is the conclusion.


Du teach sieve

Provided multiplicative function now required prefix and $ f $, provided $ \ sum \ limits_ {i = 1} ^ {n} f (i) = S (n) $.

Find a multiplicative function $ g $, consider a prefix thereof Dirichlet convolution and

$$\sum\limits_{i=1}^{n}(f*g)(i)$$

$$\begin{aligned} &= \sum\limits_{i=1}^{n} \sum \limits _{d|i} f(d)g(\frac{i}{d}) \\ &= \sum \limits _{d=1}^{n} g(d)\sum\limits _{i=1}^{\lfloor \frac{n}{d}\rfloor } f(i) \\ &= \sum \limits _{d=1}^{n} g(d) S(\lfloor \frac{n}{d} \rfloor) \end{aligned}$$

Wherein the first line is obtained according to the definition of Dirichlet convolution.

The second line is to get the proposed $ g $ enumerate $ d $.

The third line is obtained $ \ sum \ limits _ {i = 1} ^ {\ lfloor \ frac {n} {d} \ rfloor} f (i) $ replaced $ S (\ lfloor \ frac {n} {d} \ rfloor) $

Next consider $ g (1) S (n) $ equal to what.

Can be found, he is equal to $$ \ sum \ limits _ {i = 1} ^ {n} g (i) S (\ lfloor \ frac {n} {i} \ rfloor) - \ sum \ limits _ {i = 2} ^ {n} g (i) S (\ lfloor \ frac {n} {i} \ rfloor) $$

(As will be understood from the beginning of the prefix and prefix and is subtracted from the first item beginning 2)

The preceding equation $ \ sum \ limits _ {i = 1} ^ {n} g (i) S (\ lfloor \ frac {n} {i} \ rfloor) $, according to the just derived, he is equal to $ \ sum \ limits_ {i = 1} ^ {n} (f * g) (i) $

So get to teach core equation Du screen:

$$g(1)S(n)=\sum\limits_{i=1}^{n}(f*g)(i) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor)$$

After what use is it to get this formula?

Now if can find a suitable multiplicative function $ G $, making it possible to quickly calculated $ \ sum \ limits_ {i = 1} ^ {n} prefix (f * g) (i) $ and $ G $ and, then It can be solved recursively by block number theory.

Code to be understood that this can probably be written (default llis long long) (may be understood as a frame is a pseudo-code idea ..)

ll GetSum(int n) { // 算 f 前缀和的函数
  ll ans = f_g_sum(n); // 算 f * g 的前缀和
  // 以下这个 for 循环是数论分块
  for(ll l = 2, r; l <= n; l = r + 1) { // 注意从 2 开始
    r = (n / (n / l)); 
    ans -= (g_sum(r) - g_sum(l - 1)) * GetSum(n / l);
    // g_sum 是 g 的前缀和
    // 递归 GetSum 求解
  } return ans; 
}

This code is the complexity of $ O (n ^ {\ frac {3} {4}}) $, proven as follows:

Determined set $ S (n) $ complexity is $ T (n) $, requires a $ S (n) $ necessary to calculate $ \ sqrt n $ a $ S (\ lfloor \ frac {n} {i} \ rfloor) $ value, in conjunction with number theory complexity $ O chunked (\ sqrt n) $ can be obtained: $$ T (n) = \ sum \ limits_ {i = 1} ^ {\ sqrt n} O (\ sqrt i) + O (\ sqrt {\ frac {n} {i}}) = O (n ^ {\ frac {3} {4}}) $$

It can be further optimized Du teach sieve, which is to screen out front linear $ m $ answer, then after Du teach sieve. This complexity is after optimization:

$$T(n) = \sum\limits_{i=1}^{\lfloor \frac{n}{m} \rfloor} \sqrt \frac{n}{i} = O({\frac{n}{\sqrt m}})$$

When $ m = n ^ {\ frac {2} {3}} $ time, $ T (n) = O (n ^ {\ frac {2} {3}}) $

You can use a hash table to save enough has been seeking answers, you can not.

Taking into account the above summation is occurred $ \ lfloor \ frac {n} {i} \ rfloor $. Open a size twice as $ \ sqrt n $ $ dp $ records array of answers. If you need to find now GetSum(x), if $ x \ leq \ sqrt n $ , return dp[x], otherwise dp[sqrt n + n / i]you can. This will eliminate the complexity of the hash table.



Practical exercise

Once again hang core (Tao) Heart (LU) type, which all rely on: $$ g (1) S (n) = \ sum \ limits_ {i = 1} ^ {n} (f * g) (i) - \ sum \ limits _ {i = 2} ^ {n} g (i) S (\ lfloor \ frac {n} {i} \ rfloor) $$

Its key is to find the right $ g $ rapidly so that this thing can be considered.

Theoretical knowledge about so much, then look at a few examples:

(1) $ \ mu $ prefix and

Given the nature of Mobius function $ \ mu * I = \ epsilon $, naturally thought take $ f = \ mu, g = I, f * g = \ epsilon $.

Where prefix prefix and $ I $ and $ \ epsilon $ and are weak to burst. .

So it is easy to solve.

Du teach sieve Code:

inline ll GetSumu(int n) {
  if(n <= N) return sumu[n]; // sumu是提前筛好的前缀和
  if(Smu[n]) return Smu[n]; // 记忆化
  ll ret = 1ll; // 单位元的前缀和就是 1
  for(int l = 2, r; l <= n; l = r + 1) {
    r = n / (n / l); ret -= (r - l + 1) * GetSumu(n / l);
    // (r - l + 1) 就是 I 在 [l, r] 的和
  } return Smu[n] = ret; // 记忆化
}

(2) $ \ varphi $ prefix and

Considering the $ \ $ varphi properties of $ \ varphi * I = id $, take $ f = \ varphi, g = I, f * g = id $

I.e., $ f * g $ $ prefix and ID is $ $ \ frac {n * (n + 1)} {2} $

Du teach sieve Code:

inline ll GetSphi(int n) {
  if(n <= N) return sump[n]; // 提前筛好的
  if(Sphi[n]) return Sphi[n]; // 记忆化
  ll ret = 1ll * n * (n + 1) / 2; // f * g = id 的前缀和
  for(int l = 2, r; l <= n; l = r + 1) {
    r = n / (n / l); ret -= (r - l + 1) * GetSphi(n / l);
    // 同上,因为两个的 g 都是 I 
  } return Sphi[n] = ret; // 记忆化
}

(1) & (2) is to teach Du screen template luogu p4213

(3) (综合)$\sum\limits_{i=1}^{n}\varphi(i) \cdot i$

Order $ f = \ varphi \ cdot id, g = id $, consider the convolution Dealey Cray obtained in the form $ (f * g) (n) = \ sum \ limits _ {d | n} (\ varphi (d) \ cdot d) \ cdot (\ frac {n} {d}) = n \ sum \ limits_ {d | n} \ varphi (d) = n ^ 2 $

即 $(f * g)(i) = i^2$

This can be obtained quickly $ (f * g) (i) $ prefix and $ \ frac {n (n + 1) (2n + 1)} {6} $

On it.



topic

To recommend Los Valley template title

There is also a question luoguP3768 simple math formula can be used to push this question End Du teach sieve to seek $ \ varphi (i) i ^ 2 $ and prefix, and $ \ varphi (i) i $ not much different.

There are many topics to teach Du screen on 51nod, put a few:

  • 51nod 1244
  • 51nod 1237
  • 51nod 1238
  • 51nod 1239
  • 51nod 1220
  • ...

Then the card is always optimized card with the open space, unordered_map fucks.

#include<bits/stdc++.h>
#define il inline
#define co const
template<class T>T read(){
    T data=0,w=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(T&x) {return x=read<T>();}
typedef long long LL;
using namespace std;

co int N=6500000;
int pri[N],tot;
LL mu[N],phi[N];
void sieve(){
    pri[1]=mu[1]=phi[1]=1;
    for(int i=2;i<N;++i){
        if(!pri[i]) pri[++tot]=i,mu[i]=-1,phi[i]=i-1;
        for(int j=1;j<=tot&&i*pri[j]<N;++j){
            pri[i*pri[j]]=1,mu[i*pri[j]]=-mu[i],phi[i*pri[j]]=phi[i]*phi[pri[j]];
            if(i%pri[j]==0){
                mu[i*pri[j]]=0,phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
        }
    }
    for(int i=2;i<N;++i) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
unordered_map<int,LL> smu,sphi;
LL sum_mu(int n){
    if(n<N) return mu[n];
    if(smu.count(n)) return smu[n];
    LL ans=1;
    for(unsigned l=2,r;l<=n;l=r+1){ // 2^32-1
        r=n/(n/l);
        ans-=(r-l+1)*sum_mu(n/l);
    }
    return smu[n]=ans;
}
LL sum_phi(int n){
    if(n<N) return phi[n];
    if(sphi.count(n)) return sphi[n];
    LL ans=(LL)n*(n+1)/2;
    for(unsigned l=2,r;l<=n;l=r+1){
        r=n/(n/l);
        ans-=(r-l+1)*sum_phi(n/l);
    }
    return sphi[n]=ans;
}
int main(){
    cerr<<(sizeof(pri)+sizeof(phi)+sizeof(mu))/1024.0/1024<<endl;
    sieve();
    for(int t=read<int>();t--;){
        int n=read<int>();
        printf("%lld %lld\n",sum_phi(n),sum_mu(n));
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/autoint/p/11102069.html