zoukankan      html  css  js  c++  java
  • 线性筛

    数论函数

    \(f(n)\) 定义域为 \(N\) (正整数域),值域为 \(N\)
    \(f(x)=x\)\(f(x)=x^2\)

    积性函数

    对于一个函数 \(f(x)\) ,如果 \(\forall a,b,\gcd(a,b)=1,ab=x,f(a)f(b)=f(x)\) ,则称 \(f\) 是积性函数。
    证明约数和函数是积性函数:
    考虑 \(a,b(\gcd(a,b)=1,ab=x)\)
    \(f(a)f(b)=\sum \limits _{d|a}d \sum \limits _{p|b}p= \sum \limits _{d|a}\sum \limits _{p|b}dp\)
    因为 \(\gcd(a,b)=1\) ,所以 \(\gcd(d,p)=1\)
    所以 \(f(a)f(b)=\sum \limits _{d|a}d \sum \limits _{p|b}p=\sum \limits _{d|a}\sum \limits _{p|b}dp=\sum \limits _{(dp)|(ab)}dp\)
    因为 \(ab=x\) ,令 \(t=dp\)
    \(f(a)f(b)=\sum \limits _{t|x}t=f(x)\)

    埃氏筛

    for(int i=2;i<=n;i++)
    	if(p[i]) for(int j=2;i*j<=n;j++) p[i*j]=false;
    

    线性筛

    每个数被它的最小质因子筛掉。

    bool co[N]={false,true};//coprime
    int pn[N],cnt;//prime number
    for(int i=2;i<=n;i++)
    {
    	if(!co[i]) pn[++cnt]=i;
    	for(int j=1;j<=cnt;j++)
    	{
                    //pn[j]是i*pn[j]的最小质因子
    		if(i*pn[j]>n) break;
    		co[i*pn[j]]=true;
    		if(!(i%pn[j])) break;
                    //i=pn[j]*k
                    //如果继续枚举,pn[j+1]*i=pn[j+1]*pn[j]*k
                    //一定已经被 pn[j] 筛过了。
    	}
    }
    

    积性函数筛

    给出 \(n\) ,求 \(f(1),f(2), \cdots ,f(n)\) 。其中 \(f(x)= \sum \limits _{d|x} d\)

    bool co[N]={false,true};//coprime
    int pn[N],f[N]={0,1},cnt;//prime number
    int z[N];//z[i]表示p^c。其中p是i的最小质因子。p^c|i,p^{c+1} not|i
    for(int i=2;i<=n;i++)
    {
    	if(!co[i])
    	{
    		pn[++cnt]=i;
    		f[i]=i+1,z[i]=i;
    	}
    	for(int j=1;j<=cnt;j++)
    	{
    		//pn[j]是i*pn[j]的最小质因子 
    		if(i*pn[j]>n) break;
    		co[i*pn[j]]=true;
    		if(!(i%pn[j]))
    		{
    			int x=i*pn[j];
    			z[x]=z[i]*pn[j];
    			if(z[x]==x) f[x]=f[i]+x;
    			//x是pn[j]的幂。
    			//f[x]=1+pn[j]+pn[j]^2+...+pn[j]^k
    			//i=x/pn[j]
    			//f[i]=1+pn[j]+pn[j]^2+...+pn[j]^{k-1}
    			//f[x]=f[i]+pn[j]^k=f[i]+x 
    			else f[x]=f[x/z[x]]*f[z[x]];
    			//i/pn[j]/pn[j]...
    			//f[i*pn[j]]=f[i]*f[pn[j]^k]
    			
    			//pn[j]是i的最小质因子。
    			//如果继续枚举,pn[j]就不是i*pn[j]的最小质因子了。
    			break;
    		}
    		else
    		{
    			f[i*pn[j]]=f[i]*f[pn[j]];
    			z[i*pn[j]]=pn[j];
    			//i%pn[j]!=0->gcd(i,pn[j])==1
    			//pn[j]是i*pn[j]唯一的最小质因子。
    		}
    	}
    }
    

    三个要点:
    1.质数的情况
    2.\(i \perp p_j\) 的情况(\(a \perp b \Leftrightarrow \gcd(a,b)=1\)
    3.\(p_j\)\(i\) 的最小质因子的情况

    欧拉函数

    \(\varphi(n)\) 表示 \(1\)\(n\) 中与 \(n\) 互质的数的个数。
    \(\varphi(n)=\sum \limits _{i=1}^n [i \perp n]\)
    \(\varphi(n)\) :
    根据整数唯一分解定理,设 \(n=\prod \limits _{i=1}^k p_i^{c_i}\) ( \(p_i\) 是质数),
    \(\varphi(n)=n \prod \limits _{i=1}^k \left (1- \frac{1}{p_i} \right )\)

    莫比乌斯函数

    \(\mu(n)= \begin{cases} 1&n=1\\ (-1)^k&c_i=1\\ 0& \text{otherwise} \end{cases}\)
    证明 \(\mu\) 是积性函数:
    对于 \(\forall a,b,a \perp b,ab=x\) , 考虑 \(\mu(a)\mu(b)\) :
    1.若 \(\mu(a)=0\)\(\mu(b)=0\) ,则 \(ab\) 必含平方因子,则 \(\mu(ab)=\mu(a)\mu(b)=0\)
    2.否则,由于 \(a \perp b\) ,则 \(ab\) 也不含平方因子,则 \(\mu(a)\mu(b)=(-1)^{k_1}(-1)^{k_2}=(-1)^{k_1+k_2}=\mu(ab)\)

    一般线性筛

    对于一个积性函数 \(f\) ,考虑以下的线性筛法:
    要计算 \(f(n)\) ,考虑到 \(n=\prod \limits _{i=1}^k p_i^{c_i}\)
    在线性筛的过程中,如果 \(i \bmod p_j \neq 0\) ,就有 \(f(i \cdot p_j)=f(i)f(p_j)\)
    否则,考虑 \(k|(i \cdot p_j)\)\(k \perp p_j\) ,则有 \(f(i \cdot p_j)=f(k)f( \frac{i \cdot p_j}{k})\)
    因此,我们只需要记录对于每一个 \(i \cdot p_j\) 对应的 \(k\) ,和推导出从 \(f(p^c)\)\(f(p^{c+1})\) 的关系式即可。

    一个例题

    \(f(i)\) 表示有序三元组 \((a,b,c)\) 的个数,使得 \(abc=i\) 。求出 \(f(1)\) ~ \(f(n)\)\(n \leq 10^7\)
    证明 \(f\) 是积性函数
    写出式子: \(f(i)=\sum \limits_{a|i} \sum \limits_{b|i} \sum \limits_{c|i} [abc=i]\)
    显然,原式等于 \(\sum \limits_{a|i} \sum \limits_{b| \frac{i}{a}} 1\)
    \(d(n)\) 表示 \(n\) 的约数个数,
    则原式可转化为 \(\sum \limits_{a|i} d(\frac{i}{a})\)
    \(\sum \limits_{a|i} d(a)\)
    所以,要先证明 \(d\) 是积性函数。
    \(d(a)d(b)=\sum \limits_{x|a} 1 \sum \limits_{y|b} 1\)
    因为 \(a \perp b\) ,所以 \(x \perp y\)
    所以原式等于 \(\sum \limits_{(xy)|(ab)} 1\)
    所以 \(d(a)d(b)=d(ab)\)
    所以 \(d\) 是积性函数。
    所以 \(f(a)f(b)=\sum \limits_{x|a} d(x) \sum \limits_{y|b} d(y)\)
    因为 \(a \perp b\) ,所以 \(x \perp y\)
    所以原式等于 \(\sum \limits_{(xy)|(ab)} d(x)d(y)\)
    因为 \(d\) 是积性函数,
    所以原式等于 \(\sum \limits_{(xy)|(ab)} d(xy)\)
    所以 \(f(a)f(b)=f(ab)\)
    所以 \(f\) 是积性函数。
    所以就可以开始筛了。

    考虑 \(f(p^k)\)
    \(a=p^x\)\(b=p^y\)\(c=p^z\)
    那么 \(k=x+y+z\)
    用插板法可求出方案为 \(C(k+2,2)\)
    筛的时候记一下 \(k\) 即可。

  • 相关阅读:
    hdu2328 Corporate Identity
    hdu1238 Substrings
    hdu4300 Clairewd’s message
    hdu3336 Count the string
    hdu2597 Simpsons’ Hidden Talents
    poj3080 Blue Jeans
    poj2752 Seek the Name, Seek the Fame
    poj2406 Power Strings
    hust1010 The Minimum Length
    hdu1358 Period
  • 原文地址:https://www.cnblogs.com/zhs1/p/12693917.html
Copyright © 2011-2022 走看看