莫比乌斯反演2

\documentclass[12pt,UTF8,titlepage]{article}
\usepackage[colorlinks,linkcolor=blue]{hyperref}
\usepackage{fontspec}
\usepackage{xunicode}
\usepackage{xltxtra}
\usepackage{amstext}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{ulem}

\author{wcz\footnote{Contact me:\href {mailto:[email protected]}{[email protected]}}}
\title{莫比乌斯反演}
\usepackage{xeCJK}

\setmainfont[BoldFont=LinLibertine_RZah.ttf,ItalicFont=LinLibertine_RIah.ttf,BoldItalicFont=LinLibertine_RZIah.ttf]{LinLibertine_Rah.ttf}
\setsansfont[BoldFont=SourceCodePro-BoldIt.ttf,ItalicFont=SourceCodePro-Regular.ttf,BoldItalicFont=SourceCodePro-Bold.ttf]{SourceCodePro-It.ttf}
\setmonofont[BoldFont=UbuntuMono-RI.ttf,ItalicFont=UbuntuMono-BI.ttf,BoldItalicFont=UbuntuMono-B.ttf]{UbuntuMono-R.ttf}

\setCJKmainfont{KaiTi_GB2312}

\lstset{numbers=left,
numberstyle= \tiny,
keywordstyle= \color{ blue!70},commentstyle=\color{red!50!green!50!blue!50},
frame=shadowbox,
,rulesepcolor= \color{ red!20!green!20!blue!20},escapeinside=``
%xleftmargin=2em,xrightmargin=2em, aboveskip=1em}
}
\begin{document}
    \maketitle
    \tableofcontents
    \newpage
    \section{前言}
        本文内容大部分来自Oier PoPoQQQ 的课件。\        Download: \href {https://1drv.ms/p/s!AmXDWOyfksuQsT9QiF1Q8BANX4fn}{onedrive},
        \href {https://pan.baidu.com/s/1hs1WWLY}{baidu pan},密码:6ug5\        \par 本文基本上由我学习相当于是制作的一篇学习笔记,但是将课件中的一些不完善的地方加以完善
        使得更容易理解,加上了部分例题的代码

    \section{引子}
    介绍莫比乌斯反演之前我们先来看一个函数
    \begin{equation}
        F(n)=\sum_{d|n} f(d)
    \end{equation}
    \par 根据$F(n)$的定义
    \begin{align*}
        &F(1)=f(1)\\
        &F(2)=f(1)+f(2)\\
        &F(3)=f(1)+f(3)\\
        &F(4)=f(1)+f(2)+f(4)\        &F(5)=f(1)+f(5)\        &F(6)=f(1)+f(2)+f(3)+f(6)\        &F(7)=f(1)+f(7)\        &F(8)=f(1)+f(2)+f(4)+f(8)\        &\cdots
    \end{align*}
    \par 于是我们便可以通过$F(n)$推导出$f(n)$
    \begin{align*}
        &f(1)=F(1)\\
        &f(2)=F(2)-F(1)\\
        &f(3)=F(3)-F(1)\\
        &f(4)=F(4)-F(2)\\
        &f(5)=F(5)-F(1)\\
        &f(6)=F(6)-F(3)-F(2)+F(1)\\
        &f(7)=F(7)-F(1)\\
        &f(8)=F(8)-F(4)\\
        &\cdots
    \end{align*}
    \par 在推导的过程中我们是否发现了一些规律?

\newpage

    \section{莫比乌斯反演}
    莫比乌斯反演\footnote{baike:莫比乌斯反演是数论数学中很重要的内容,可以用于解决很多组合数学的问题。}
    \subsection{莫比乌斯反演定义}
        \begin{equation}
            F(n)=\sum_{d|n} f(n)=\sum_{d|n}\mu(d)f(\frac{n}{d})
        \end{equation}
        \par 其中$\mu(d)$为莫比乌斯函数\label{1},定义如下

        \begin{equation}
            \mu(d)=
            \begin{cases}
                1, &d=0\\
                (-1)^k, &d=p_1p_2\cdots p_k,\forall p_i!=p_j\\
                0, &others
            \end{cases}
        \end{equation}
        \par  莫比乌斯函数的定义式\footnote{$\mu(n)=\delta_{\varpi(n)\Omega(n)}\lambda(n)$}

    \subsection{莫比乌斯函数的性质}

    \subsubsection*{(1)}
    当n不等于1时,n所有因子的莫比乌斯函数值的和为0,\    \par 设$$F(n)=\sum_{d|n} \mu(d)$$
        \par 那么
        \begin{align}
            F(n)=
            \begin{cases}
                1, &n=1\                0, &n>0
            \end{cases}
        \end{align}

        证明:
        \begin{align*}
        \textcircled{1}&
        \text{当$n=1$的时候显然成立} \        \textcircled{2}&\text{当$n\not = 1$时},n=p_1^{a_1}p_2^{a_2} \cdots p_k^{a_k}\        &\because \mu(d)\not =0\Leftrightarrow d=p_1p_2\cdots p_t\        &\text{质因子个数为$r$的因子只有$C_k^r$个}\        &\therefore F(x)=C_k^0-C_k^1+C_k^2+\cdots +(-1)^kC_k^k=\sum_{i=0}^{k}(-1)^iC_k^i\        &\text{接下来只需证明}\sum_{i=0}^n(-1)^iC_n^i=0(n\in N_+)\text{即可}\        &\text{因为二项式定理}\        &(x+y)^n=\sum_{i=0}^nC_n^ix^iy^{n-i}\        &\text{令}x=-1,y=1,\text{代入即可得证。}
        \end{align*}

    \subsubsection*{(2)}对于$n\in N_+$有:
        \begin{equation}
            \sum_{d|n}\frac{\mu(d)}{d}=\frac{\phi(n)}{n}
        \end{equation}
        \begin{align*}
        &\text{只需要令}F(n)=n,f(n)=\phi(n),\        &\text{代入}F(n)=\sum_{d|n} f(n)=\sum_{d|n}\mu(d)f(\frac{n}{d})\text{即可}\        &\text{那么就有}n=\sum_{d|n}\phi(d)\text{为什么成立?}
        \end{align*}

    \subsubsection*{(3)}积性函数
        数论上积性函数的定义\        \begin{align*}
        &\text{设函数$f(n),其中n\in N+$}\        &\text{对于任意$(x,y)=1$都有$f(xy)=f(x)f(y)$},\        &\text{则称$f(n)$为一个积性函数;}\        &\text{若对于任意$x,y$都有$f(xy)=f(x)f(y)$},\        &\text{则称$f(n)$为一个完全积性函数。}\        \end{align*}
        \par 积性函数的性质\        \par \textcircled{1}$f(1)=1$\        \par \textcircled{2}积性函数的前缀和也是积性函数\        \\ 

        \par 因为积性函数是积性函数,\par 因此可以通过线性筛求出莫比乌斯函数的值
\begin{lstlisting}[language={[ANSI]C}]
mu[1]=1;
for(i=2;i<=n;i++){
    if(!not_prime[i]){
        prime[++tot]=i;
        mu[i]=-1;
    }
    for(j=1;prime[j]*i<=n;j++){
        not_prime[prime[j]*i]=1;
        if(i%prime[j]==0){
            mu[prime[j]*i]=0;
            break;
        }
        mu[prime[j]*i]=-mu[i];
    }
}
\end{lstlisting} 

\subsubsection {例题1:}
\href {http://www.lydsy.com/JudgeOnline/problem.php?id=2440}{BZOJ 2440 完全平方数}\\par {题目大意}:求第k个无平方因子数\footnote{无平方因子数(Square-Free Number),即分解之后所有质因数的次数都为1的数}\\par 做法:
    首先二分答案,问题转化为求$\left[1,x\right]$之间有多少个无平方因子数\    根据容斥原理可知,对于$sqrt(x)$之内所有的质数,
    答案G(x)=0个质数平方倍数的个数-1个质数平方倍数的个数+2个质数平方倍数的个数-...,
    那么对于偶数个质数平方对于答案的贡献就是正的,否则是负的,\\如果不是若干个互异质数的乘积,那么对答案没有影响,
    \par 如何表示这个式子呢?\    \par 观察莫比乌斯函数的定义\ref{1},可以知道对于能对答案产生贡献的数$x$,$\mu(x)=(-1)^k$,其中$k$为$x$分解得到质数的个数
    根据上述说明,那么可以得知结果\    \begin{equation}
        G(x)=\sum_{i=1}^{\lfloor \sqrt{x}\rfloor}\mu(i)\lfloor \frac{x}{i^2}\rfloor
    \end{equation}
\begin{lstlisting}[language={[ANSI]C}]
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 100005
using namespace std;

bool not_prime[N];
int prime[N];
int mu[N];
int tot;

void Mu(int n){
    int i,j;
    mu[1]=1;
    for(i=2;i<=n;i++){
        if(!not_prime[i]){
            prime[++tot]=i;
            mu[i]=-1;
        }
        for(j=1;prime[j]*i<=n;j++){
            not_prime[prime[j]*i]=1;
            if(i%prime[j]==0){
                mu[prime[j]*i]=0;
                break;
            }
            mu[prime[j]*i]=-mu[i];
        }
    }
}
int can(int x){
    int sum=0;
    int s=floor(sqrt(x));
    for(int i=1;i<=s;++i)
        if(mu[i])
           sum+=mu[i]*floor(x/(i*i));
    return sum;
}

int main(){
    Mu(N);int T,sum;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&num);
        long long l=1,r=num<<1,mid;
        while(l<r){
            mid=(l+r)>>1;
            if(can(mid)<num)
                l=mid+1;
            else r=mid;
        }
        printf("%lld\n",r);
    }
    return 0;
}
\end{lstlisting} 

    \subsection{莫比乌斯反演定理的证明}

    \begin{equation}
        F(n)=\sum_{d|n}f(d)\Rightarrow f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})
    \end{equation}

    证明:
        \begin{align*}
            f(n)=&\sum_{d|n}\mu(d)F(\frac{n}{d})\                =&\sum_{d|n}\mu(d)\sum_{k|\frac{n}{d}}f(k)\                =&\sum_{k|n}f(k)\sum_{d|\frac{n}{k}}\mu(d)\                =&f(n)
        \end{align*}
    形式二:
        \begin{equation}
            F(n)=\sum_{n|d}f(d)\Rightarrow f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)
        \end{equation}
        证明同理,一般要用到的都是这种形式
    \subsection{莫比乌斯反演的应用}
    \par 主要是用于处理一些组合数问题。
    \par 对于一些函数$f(n)$,如果我们很难直接求出它的值,而容易求出倍数和或约数和$F(n)$,
    那么我们可以直接利用莫比乌斯反演来求得$f(n)$的值。
    \paragraph{例:}
        f(n)表示某一范围内(x,y)=n的数对的数量,\        F(n)表示某一范围内n|(x,y)的数对的数量\        那么直接求f(n)并不是很好求,而F(n)求起来相对无脑一些,\        那么我们可以通过对F(n)进行莫比乌斯 反演来求得f(n)。\        

    \subsubsection{例题2:}
    \href {http://www.lydsy.com/JudgeOnline/problem.php?id=2301}{BZOJ 2301 Problem b}
    \par 题目大意:询问有多少对$(x,y)$满足$x\in \left[ a,b\right] ,y\in \left[ c,d \right] $且$(x,y)=k$。
    \par 根据容斥原理,这个题目就可以转化成
        \begin{align*}
            s_1=&\sum_{i=1}^{b}\sum_{j=1}^{d}\left[ (i,j)=k \right]\            s_2=&\sum_{i=1}^{a-1}\sum_{j=1}^{d}\left[ (i,j)=k \right]\            s_3=&\sum_{i=1}^{b}\sum_{j=1}^{c-1}\left[ (i,j)=k \right]\            s_4=&\sum_{i=1}^{a-1}\sum_{j=1}^{c-1}\left[ (i,j)=k \right]
        \end{align*}
        \par 其中答案为$s_1-s_2-s_3+s_4$\    \par 那么我们需要快速求出
    \begin{equation}
        \sum_{i=1}^a\sum_{j=1}^b \left[ (i,j)=k \right]
    \end{equation}
    \par 这个式子可以进一步转化为
    \begin{equation}
        \sum_{i=1}^{\lfloor \frac{a}{k}\rfloor}\sum_{j=1}^{\lfloor \frac{b}{k}\rfloor }\left[ (i,j)=k \right]
    \end{equation}
    \par 考虑莫比乌斯反演,
    令
    \begin{align}
        f(k)=&\sum_{i=1}^{a}\sum_{j=1}^{b} \left[ (i,j)=k \right]\        F(k)=&\sum_{i=1}^{a}\sum_{j=1}^{b} \left[ k|(i,j)\right]\            =&\lfloor \frac{a}{k}\rfloor \lfloor \frac{b}{k}\rfloor\            \text{反演后可得}f(k)=&\sum_{k|d}\mu(\frac{d}{k})F(d)\            =&\sum_{k|d}\mu(\frac{d}{k})\lfloor \frac{a}{d}\rfloor \lfloor \frac{b}{d}\rfloor
    \end{align}
    \par 分析可知这个算法的复杂度是$\Theta(n)$
    \par 我们还需要对这个算法进行进一步优化
    \par 因为$\lfloor \frac{a}{d}\rfloor $至多只有$2\sqrt{a}$个取值,
    \par 那么$\lfloor \frac{a}{d}\rfloor \lfloor \frac{b}{d}\rfloor$至多只有$2(\sqrt{a}+\sqrt{b})$个取值
    \par 因为使得$\lfloor \frac{a}{d}\rfloor \lfloor \frac{b}{d}\rfloor==i$成立的$i$值都是连续的,
    \par 所以可以维护一个莫比乌斯函数的前缀和,
    \par 这样就可以在$\Theta(\sqrt{n})$的时间内出解
    \par {\color{red}枚举除法的取值在莫比乌斯反演的应用当中非常常用\label{2}}
\begin{lstlisting}[language={[ANSI]C}]
if(a>b)swap(a,b);
for(i=1;i<=a;i=last+1){
    last=min(a/(a/i),b/(b/i));
    re+=(a/i)*(a/i)*(sum[last]-sum[i-1]);
}
return re;
\end{lstlisting}
     \newpage
     代码异常好写
\begin{lstlisting}[language={[ANSI]C}]
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 50005
#define inf 0x7fffffff
using namespace std;

bool not_prime[N];
int prime[N];
int sum[N];
int mu[N];
int tot;

void Mu(int n){
    int i,j;
    mu[1]=1;
    for(i=2;i<=n;i++){
        if(!not_prime[i]){
            prime[++tot]=i;
            mu[i]=-1;
        }
        for(j=1;prime[j]*i<=n;j++){
            not_prime[prime[j]*i]=1;
            if(i%prime[j]==0){
                mu[prime[j]*i]=0;
                break;
            }
            mu[prime[j]*i]=-mu[i];
        }
    }
    for(int i=1;i<=n;++i)
        sum[i]=sum[i-1]+mu[i];
}
int ans(int n,int m){
    if(n>m)swap(n,m);
    int last,i,re=0;
    for(i=1;i<=n;i=last+1){
        last=min(n/(n/i),m/(m/i));
        re+=(n/i)*(m/i)*(sum[last]-sum[i-1]);
    }
    return re;
}

int main(){
    Mu(N);
    int T;
    int a,b,c,d,k;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        a--;c--;
        a/=k;b/=k;c/=k;d/=k;
        int Ans=ans(b,d)-ans(a,d)-ans(b,c)+ans(a,c);
        printf("%d\n",Ans);
    }
    return 0;
}
\end{lstlisting}
    BZOJ 10s但是luogu却莫名WA\    全部加上long long 之后总算是过了\    百思不得其解
    \newpage
    \subsubsection{例题3}
        \href{http://www.lydsy.com/JudgeOnline/problem.php?id=2820}{BZOJ 2820 YY的GCD}\        题目大意:求有多少数对$(x,y)$满足$x\in \left[ 1,n\right] ,y\in \left[ 1,m \right] $满足$(x,y)$为质数
        做法:
        \par 首先这个题目和上一个题目不一样的地方是他需要一个特殊的转化
        \begin{align}
        \text{令}
            k=&min(n,m);\            ans=&\sum_{p}^k\sum_{i=1}^n\sum_{j=1}^m\left[ (i,j)=p\right] \            =&\sum_{p}^k\sum_{d=1}^k \mu(d)\lfloor \frac{n}{pd}\rfloor \lfloor
 \frac{m}{pd}\rfloor \        \text{令}T=&pd\        ans=&\sum_{T=1}^{k}\lfloor \frac{n}{T}\rfloor \lfloor \frac{m}{T}\rfloor \sum_{p|T}^{k}\mu(\frac{T}{p})\        \text{令}F(k)=&\sum_{p|T}^k\mu(\frac{T}{p})\        \text{则}ans=&\sum_{T=1}^kF(k)\lfloor \frac{n}{T}\rfloor \lfloor \frac{m}{T}\rfloor \        \end{align}
        线性筛素数的时候对$F(k)$前缀和处理\        然后就转变为和例二\ref{2}一样的做法,枚举除法的取值了\\begin{lstlisting}[language={[ANSI]C}]
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 10000000
#define ll long long
using namespace std;

bool not_prime[N];
ll prime[N];
ll sum[N];
ll mu[N];
ll tot;

void Mu(int n){
    mu[1]=1;
    for(int i=2;i<=n;i++){
        if(!not_prime[i]){
            prime[++tot]=i;
            mu[i]=-1;
        }
        for(int j=1;prime[j]*i<=n;j++){
            not_prime[prime[j]*i]=1;
            if(i%prime[j]==0){
                mu[prime[j]*i]=0;
                break;
            }
            mu[prime[j]*i]=-mu[i];
        }
    }
    for(int i=1;i<=tot;++i)
        for(int j=1;j*prime[i]<=n;++j)
            sum[j*prime[i]]+=(ll)mu[j];
    for(int i=1;i<=n;++i)
        sum[i]+=(ll)sum[i-1];
}

ll ans(int n,int m){
    if(n>m)swap(n,m);
    int last,i;ll re=0;
    for(i=1;i<=n;i=last+1){
        last=min(n/(n/i),m/(m/i));
        re+=(ll)(n/i)*(m/i)*(sum[last]-sum[i-1]);
    }
    return re;
}

int main(){
    Mu(N);
    int T;
    int a,b;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&a,&b);
        ll Ans=ans(a,b);
        printf("%lld\n",Ans);
    }
    return 0;
}
?\end{lstlisting}
这已经是第n次被long long卡一个小时以上了
\newpage
    \subsubsection{例题4:}
    \href{http://www.lydsy.com/JudgeOnline/problem.php?id=3529}{BZOJ 3529: [Sdoi2014]数表}\    \href{http://blog.csdn.net/PoPoQQQ/article/details/42076231}{选择膜拜Po爷}\    \par 题目大意:令F(i)为i的约数和,给定n,m,a,求\        $$\sum_{F(d)\leq a}F((i,j)=d)$$
    因为a的限制非常讨厌,所以我们先忽略它的存在\    令$Z=min(n,m)$
    \begin{align*}
    \text{令}g(i)=&\sum\left[(x,y)=i \right]\    \text{那么显然有}g(i)=&\sum_{i|d}\mu(\frac{d}{i})\lfloor \frac{n}{d}\rfloor \lfloor \frac{m}{d}\rfloor \    \because (i,j)=&d,d=p_1^{a_1}p_2^{a_2}\cdots p_k^{a_k}\    \text{由约数和定理得}F(d)=&(p_1^0+p_1^1+\cdots +p_1^{a_1})(p_2^0+p_2^1+\cdots +p_2^{a_2})\cdots (p_k^0+p_k^1+\cdots p_k^{a_k})\    \therefore F(pq)=&F(p)F(q),(p,q)=1\    \text{$F(i)$可}&\text{以利用线性筛在$O(n)$时间内处理出来,那么就有}\    ans=&\sum_{i=1}^{Z}F(i)g(i)\    =&\sum_{d=1}^{Z}\lfloor \frac{n}{d}\rfloor \lfloor \frac{m}{d}\rfloor \sum_{i|d}F(i)\mu(\frac{d}{i})
    \end{align*}
    然后我们可以发现最后这个式子的形式和上面非常像\    然后利用上述前缀和和枚举除法取值的方法就可以完成\
    \par 可是题目中还有一个$a$的限制,
    我们可以发现对答案有贡献的只有$F(i)\leq a$$i$\    \par 可以离线来处理这个东西,
    将询问按照$a$从小到大排序,将$F(i)$按照从小到大的顺序排序,
    每次询问之前将所有$F(i)\leq a$插入并且用树状数组维护前缀和。
    当然还有一个需要注意的问题是取模\footnote{取模可以利用自然溢出$int$最后再对$2^{31}-1$取与即可}\    接连做了好几道题都有喜闻乐见的\textsl{除法分块\ref{2}}
    \newpage
\begin{lstlisting}[language={[ANSI]C}]
#include<algorithm>
#include<iostream>
#include<cstdio>
#define N 100005
#define inf 0x7fffffff
#define ll long long
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int Q,mx,cnt;
struct data{
    int n,m,a,id;
}q[N];
bool operator<(data a,data b){
    return a.a<b.a;
}
pair<int,int>F[N];
int pri[N],mu[N];
int ans[N],t[N];
bool mark[N];
void add(int x,int val){
    for(int i=x;i<=mx;i+=i&-i)t[i]+=val;
}
int query(int x){
    int tmp=0;for(int i=x;i;i-=i&-i)tmp+=t[i];return tmp;
}
int Query(int l,int r){
    return query(r)-query(l-1);
}
void getmu(){
    mu[1]=1;
    for(int i=2;i<=mx;i++){
        if(!mark[i])pri[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&pri[j]*i<=mx;j++){
            mark[pri[j]*i]=1;
            if(i%pri[j]==0){mu[pri[j]*i]=0;break;}
            else mu[pri[j]*i]=-mu[i];
        }
    }
    for(int i=1;i<=mx;i++)
        for(int j=i;j<=mx;j+=i)
            F[j].first+=i;
    for(int i=1;i<=mx;i++)F[i].second=i;
}
void solve(int x){
    int id=q[x].id,n=q[x].n,m=q[x].m;
    for(int i=1,j;i<=q[x].n;i=j+1){
        j=min(n/(n/i),m/(m/i));
        ans[id]+=(n/i)*(m/i)*Query(i,j);
    }
}
int main(){
    Q=read();
    for(int i=1;i<=Q;i++){
        q[i].n=read();q[i].m=read();q[i].a=read();
        q[i].id=i;if(q[i].n>q[i].m)swap(q[i].n,q[i].m);
        mx=max(mx,q[i].n);
    }
    getmu();int now=0;
    sort(q+1,q+Q+1);sort(F+1,F+mx+1);
    for(int i=1;i<=Q;i++){
      while(now+1<=mx&&F[now+1].first<=q[i].a){
      for(int j=F[++now].second;j<=mx;j+=F[now].second)
                add(j,F[now].first*mu[j/F[now].second]);
        }solve(i);
    }
    for(int i=1;i<=Q;i++)
        printf("%d\n",ans[i]&inf);
    return 0;
}
\end{lstlisting}

\subsubsection{例题5:}
\href{http://www.lydsy.com/JudgeOnline/problem.php?id=2154}{BZOJ 2154:Crash的数字表格}\据说和\href{https://www.luogu.org/problemnew/show/P3768}{\color{blue} "luogu P3768"}惊人的相似\\
\par 题目大意:给定$n,m$,求$$\sum_{i=1}^n\sum_{j=1}^m\left[ i,j\right] $$
\sout {感觉有点慌,完整的公式推导花了两页}
\subsubsection{例题6:}
\href{http://www.lydsy.com/JudgeOnline/problem.php?id=2693}{BZOJ 2693: jzptab}\据说和上题惊人的相似\\
\sout {就是上题加强了数据}
做法依旧很鬼畜
\end{document}
时间: 2024-10-05 12:22:08

莫比乌斯反演2的相关文章

bzoj 2820 / SPOJ PGCD 莫比乌斯反演

那啥bzoj2818也是一样的,突然想起来好像拿来当周赛的练习题过,用欧拉函数写掉的. 求$(i,j)=prime$对数 \begin{eqnarray*}\sum_{i=1}^{n}\sum_{j=1}^{m}[(i,j)=p]&=&\sum_{p=2}^{min(n,m)}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{p}\rfloor}[i⊥j]\newline&=&\sum_{p=

hdu1695(莫比乌斯反演)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意: 对于 a, b, c, d, k . 有 x 属于 [a, b],  y 属于 [c, d], 求 gcd(x, y) = k 的 x, y 的对数 . 其中 a = b = 1 . 注意: (x, y), (y, x) 算一种情况 . 思路: 莫比乌斯反演 可以参考一下: http://blog.csdn.net/lixuepeng_001/article/details/5057

算法学习——莫比乌斯反演(1)

.. 省选GG了,我果然还是太菜了.. 突然想讲莫比乌斯反演了 那就讲吧! 首先我们看一个等式-- (d|n表示d是n的约束) 然后呢,转换一下 于是,我们就发现! 没错!F的系数是有规律的! 规律is here! 公式: 这个有什么卵用呢? 假如说有一道题 F(n)可以很simple的求出来而求f(n)就比较difficult了,该怎么办呢? 然后就可以用上面的式子了 是莫比乌斯函数,十分有趣 定义如下: 若d=1,则=1 若d=p1*p2*p3...*pk,且pi为互异素数,则=(-1)^k

bzoj2301 [HAOI2011]Problem b【莫比乌斯反演 分块】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2301 很好的一道题.首先把每个询问转化为4个子询问,最后的结果就是这四个子询问的记过加加减减,类似二维前缀和.那么问题转化为在1 <= x <= lmtx, 1 <= y <= lmty时gcd(x, y) == k的对数,这个问题在转化一下,转化成1 <= x <= lmtx / k,1 <= y <= lmty / k时x与y互质的对数.莫比乌斯反

BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演

分析:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 然后对于求这样单个的gcd(x,y)=k的,我们通常采用莫比乌斯反演 但是,时间复杂度是O(n*(n/k))的,当复杂度很坏的时候,当k=1时,退化到O(n^2),超时 然后进行分块优化,时间复杂度是O(n*sqrt(n)) #include<cstdio> #include<cstring> #include<queue

BZOJ2005: [Noi2010]能量采集 莫比乌斯反演的另一种方法——nlogn筛

分析:http://www.cnblogs.com/huhuuu/archive/2011/11/25/2263803.html 注:从这个题收获了两点 1,第一象限(x,y)到(0,0)的线段上整点的个数是gcd(x,y) 2,新学了一发求gcd(x,y)=k有多少对的姿势,已知0<x<=n,0<y<=m 令x=min(n,m),令f[i]代表gcd(x,y)=i的对数, 那么通过O(xlogx)的复杂度就可以得到f[1]到f[n](反着循环) 普通的容斥(即莫比乌斯反演)其实也

容斥原理与莫比乌斯反演的关系

//容斥原理,c[i]表示i当前要算的次数,复杂度和第二层循环相关 O(nlogn~n^2) LL in_exclusion(int n,int *c) { for(int i=0;i<=n;i++) c[i]=1; //不一定是这样初始化,要算到的才初始化为1 LL ans=0; for(int i=0;i<=n;i++) if(i要算) { ans+=(统计数)*c[i]; for(int j=i+1;j<=n;j++) if(i会算到j) c[j]-=c[i];//j要算的次数减去

BZOJ 1114 Number theory(莫比乌斯反演+预处理)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=71738 题意:给你一个整数序列a1, a2, a3, ... , an.求gcd(ai, aj) = 1 且 i < j的对数. 思路:利用莫比乌斯反演很快就能得到公式,但是求解时我们要知道序列中1, 2, 3, ... , max(a1, a2, ... , an)的倍数各是多少.我们用num[i]=k,来表示序列中有k个数是i的倍数,那么这部分对结果的影响是m

ACdream 1114(莫比乌斯反演)

传送门:Number theory 题意:给n个数,n 和 每个数的范围都是 1---222222,求n个数中互质的对数. 分析:处理出每个数倍数的个数cnt[i],然后进行莫比乌斯反演,只不过这里的F(i)=cnt[i]*(cnt[i]-1)/2. #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #include <cstring> #include <st

ACdream 1148(莫比乌斯反演+分块)

传送门:GCD SUM 题意:给出N,M执行如下程序:long long  ans = 0,ansx = 0,ansy = 0;for(int i = 1; i <= N; i ++)   for(int j = 1; j <= M; j ++)       if(gcd(i,j) == 1) ans ++,ansx += i,ansy += j;cout << ans << " " << ansx << " &qu