關於Mobius反演

来源:https://www.cnblogs.com/wasa855/archive/2019/02/17/10392439.html
-Advertisement-
Play Games

歐拉函數 $\varphi$ $\varphi(n)=$表示不超過 $n$ 且與 $n$ 互質的正整數的個數 $$\varphi(n)=n\cdot \prod_{i=1}^{s}(1 \frac{1}{p_i})$$ 其中 $n = {p_1}^{\alpha1} \cdot {p_2}^{\al ...


歐拉函數 \(\varphi\)

\(\varphi(n)=\)表示不超過 \(n\) 且與 \(n\) 互質的正整數的個數
\[\varphi(n)=n\cdot \prod_{i=1}^{s}(1-\frac{1}{p_i})\]
其中 \(n = {p_1}^{\alpha1} \cdot {p_2}^{\alpha2} \cdots {p_s}^{\alpha s} \cdot\)\(n\) 的標準分解。
由此易見 \(\text{Euler}\) 函數是積性函數。

線性求 \(\text{Euler}\) 函數:

#define int long long
int phi[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getphi()
{
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(mark[i]==false)
        {
            prime[++tot]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=tot;j++)
        {
            if(i*prime[j]>n)
            {
                break;
            }
            mark[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
    for(int i=1;i<=n;i++)
    {
        phi[i]+=phi[i-1];
    }
}

\(\text{Mobius}\)函數 \(\mu(n)\)

\[ \mu(n)= \begin{cases} 1&n=1\\ 0&n\text{ 含有平方因數}\\ (-1)^k&k\text{ 為 }n\text{ 的本質不同質因數個數}\ \end{cases} \]
證明:
\[ \varepsilon(n)= \begin{cases} 1&n=1\\ 0&n\neq 1\ \end{cases} \]

其中 \(\displaystyle\varepsilon(n)=\sum_{d\mid n}\mu(d)\)\(\varepsilon=\mu*1\)

\(\displaystyle n=\prod_{i=1}^k{p_i}^{c_i},n'=\prod_{i=1}^k p_i\)

那麼 \(\displaystyle\sum_{d\mid n}\mu(d)=\sum_{d\mid n'}\mu(d)=\sum_{i=0}^k C_k^i\cdot(-1)^k\)

根據二項式定理,易知該式子的值在 \(k=0\)\(n=1\) 時值為 \(1\) 否則為 \(0\) ,這也同時證明瞭 \(\displaystyle\sum_{d\mid n}\mu(d)=[n=1]\)

#define int long long
int mu[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getmu()
{
    mu[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(mark[i]==false)
        {
            prime[++tot]=i;
            mu[i]=-1;
        }
        for(int j=1;j<=tot;j++)
        {
            if(i*prime[j]>n)
            {
                break;
            }
            mark[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                mu[i*prime[j]]=0;
                break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
}

\(\text{Dirichlet}\)捲積

\(\text{ID}:\text{ID(i)=i}\)
\(\text{1}:\text{1(i)=1}\)
定義兩個數論函數的\(\text{Dirichlet}\)捲積為:
\[(f*g)(n)=\sum_{d|n}({f(d)\times g(\frac{n}{d})}) \]
性質:\(\text{Dirichlet}\)捲積滿足交換律和結合律。
單位元:\(\varepsilon\)\(\varepsilon(n)=[n==1]\),任何函數捲\(\varepsilon\)都為其本身.
\(1*\mu=\varepsilon\)
\(\mu * \text{ID} = \varphi\)
\(1*\text{ID}=\sigma\)

莫比烏斯反演

公式:設 \(f(n),g(n)\) 為兩個數論函數。
如果有
\[ f(n)=\sum_{d\mid n}g(d) \]
那麼有
\[ g(n)=\sum_{d\mid n}\mu(\frac{n}{d})f(d) \]
證明:
原命題等價於:已知 \(f=g*1\) ,證明 \(g=f*\mu\)
顯然: \(f*\mu=g*1*\mu= g*\varepsilon=g\) (其中 \(1*\mu=\varepsilon\)

同時,還有另一種\(\text{Mobius}\)反演:
如果有
\[ f(n)=\sum_{n\mid d}g(d) \]
那麼有
\[ g(n)=\sum_{n\mid d}\mu(\frac{d}{n})f(d) \]

整除分塊

當遇到形如
\[\sum_{i=1}^{n}\lfloor \frac{n}{i} \rfloor\]
的柿子時。
可以採用\(O(\sqrt {n})\)複雜度的演算法:整除分塊
易證:對於部分連續的\(i\)\(\frac{n}{i}\)的值是相同的,考慮把它們合併計算,可以發現發現對於每一個值相同的塊,它的最後一個數是n/(n/i)
簡略證明:\(\frac{n}{i}\)就是所求的值,設為\(x\),那麼可證對於值\(x\),它所在的塊的最後一個數是\(\frac{n}{x}\)

  • 證明:反證法:對於數\(\frac{n}{x}+1\),它所在的塊的值為\(\frac{n}{\frac{n}{x}+1}\),且\(\frac{n}{\frac{n}{x}+1}-x=\frac{x^2}{n+x}>0\)。$\therefore \(數\)\frac{n}{x}+1 \(和數\)\frac{n}{x}$不在同一個塊中。
    然後,原命題得證。

所以,易得計算原式方法。

for(int l=1,r;l<=n;l=r+1)
{
    r=n/(n/l);
    ans+=(r-l+1)*(n/l);
}

P2257 YY的GCD

\(f(d)=\sum_{i=1}^{n}\sum_{i=1}^{m}[gcd(i,j)=d]\)
\(F(n)=\sum_{n\mid d}f(d)=\lfloor \frac{N}{n} \rfloor \times \lfloor \frac{M}{n} \rfloor\)
由莫比烏斯反演:\(f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)\)

\(Ans=\sum_{i=1}^{n}\sum_{i=1}^{m}[gcd(i,j)=prim]\)
\(=\sum_{p\in prim}\sum_{i=1}^{n}\sum_{i=1}^{m}[gcd(i,j)=p]\)
\(=\sum_{p\in prim}f(p)\)
\(=\sum_{p\in prim}\sum_{p|d}\mu(\frac{d}{p})F(d)\)
改為枚舉\(\frac{d}{p}\)
\(Ans=\sum_{p\in prim}\sum_{i}^{min(\lfloor \frac{n}{p} \rfloor,\lfloor \frac{m}{p} \rfloor)}\mu(i)F(dp)\)
\(=\sum_{p\in prim}\sum_{d}^{min(\lfloor \frac{n}{p} \rfloor,\lfloor \frac{m}{p} \rfloor)}\mu(d) \times \lfloor \frac{N}{dp} \rfloor \times \lfloor \frac{M}{dp} \rfloor\)
\(dp=T,t=p\)
\(Ans=\sum_{t\in prim}\sum_{d}^{min(\lfloor \frac{n}{t} \rfloor,\lfloor \frac{m}{t} \rfloor)}\mu(\frac{T}{t}) \times \lfloor \frac{N}{T} \rfloor \times \lfloor \frac{M}{T} \rfloor\)
\(=\sum_{T=1}^{min(n,m)}\sum_{t\in prim,t|T}\mu(\frac{T}{t}) \times \lfloor \frac{N}{T} \rfloor \times \lfloor \frac{M}{T} \rfloor\)
\(=\sum_{T=1}^{min(n,m)}(\lfloor \frac{N}{T} \rfloor \times \lfloor \frac{M}{T} \rfloor) \times \sum_{t\in prim,t|T}\mu(\frac{T}{t})\)

代碼:
//sum即為\(\sum_{t\in prim,t|T}\mu(\frac{T}{t})\)的首碼和

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int prime[10000005];
int mu[10000005];
ll f[10000005];
ll sum[10000005];
bool vis[10000005];
int cnt;
void init()
{
    mu[1]=1;
    for(int i=2;i<=10000000;i++)
    {
        if(vis[i]==false)
        {
            mu[i]=-1;
            prime[++cnt]=i;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=cnt;i++)
    {
        for(int j=1;j*prime[i]<=10000000;j++)
        {
            f[j*prime[i]]+=mu[j];
        }
    }
    for(int i=1;i<=10000000;i++)
    {
        sum[i]=sum[i-1]+f[i];
    }
}
ll solve(int a,int b)//運用整除分塊
{
    ll ans=0;
    if(a>b)
    {
        swap(a,b);
    }
    for(int l=1,r=0;l<=a;l=r+1)
    {
        r=min(a/(a/l),b/(b/l));
        ans+=(ll)(sum[r]-sum[l-1])*(a/l)*(b/l);
    }
    return ans;
}
signed main()
{
    init();
    int T;
    cin>>T;
    for(int i=1;i<=T;i++)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        printf("%lld\n",solve(a,b));
    }
    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 思路 首先想到費用流。 對於每個點拆點。然後考慮我們怎樣才能保證每個點只被用一次。 如果$i$與$j$滿足條件。那麼就從$i$向$j$連一條邊並且從$j$向$i$連一條 ...
  • 原創文章,轉載請標註出處:[《Java基礎系列 Comparable和Comparator》](https://www.jianshu.com/p/f9870fd05958 一、概述 & 160;& 160;& 160;& 160;& 160;& 160;& 160;& 160;Java中的排序是由 ...
  • 抽時間複習 ...
  • 前言 只有光頭才能變強。 文本已收錄至我的GitHub倉庫,歡迎Star: "https://github.com/ZhongFuCheng3y/3y" 大年初二,朋友問了我一個技術的問題(朋友實在是好學,佩服!) 該問題來源知乎(synchronized鎖問題): "https://www.zhi ...
  • JDBC簡介 JDBC全稱為:Java Data Base Connectivity (java資料庫連接),可以為多種資料庫提供填統一的訪問。JDBC是sun開發的一套資料庫訪問編程介面,是一種SQL級的API。它是由java語言編寫完成,所以具有很好的跨平臺特性,使用JDBC編寫的資料庫應用程式 ...
  • 一.HashMap 簡介 HashMap在程式員的開發過程中是一個十分常用的集合類,它是一個以鍵值對形式存在的集合類, 在開發中我們可以利用的它的一個key存在即替換的特性,實現一個更新的去重的操作。 在另一個方便我們可以利用map跟fastJson快速組成我們所需的json數據格式。 在jdk1. ...
  • 題目: 思路: 進位轉換,26個字母的全排列相當於是26進位。既然題目要求倒數序列,那麼乾脆直接從zzz往前排好了,z對應十進位的0,y對應十進位的1,依次類推,a對應25。可以拿十進位的一個數做個例子對應26進位來看,該如何取模求餘。不然像我這樣的糊塗容易搞錯。。。 然後定義一個6位數組(因為L最 ...
  • 方式一: 方式二: 方式三: 方式四: 完畢!!! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...