zoukankan      html  css  js  c++  java
  • 浅谈杜教筛

    来重温一下杜教筛,由于生物历史会考,有一阵子没写了……

    狄利克雷卷积

    有两个函数(f,g,) 它们的狄利克雷卷积为 ((f*g)=sum_{d|n}f(d)g(frac{n}{d}).)

    由定义得,狄利克雷卷积满足交换律,结合律。

    常见狄利克雷卷积:

    (mu*id=varphi,mu*1=varepsilon,id*1= ho,1*1=d,d)函数是约数个数.

    杜教筛

    考虑求(f(i))的前缀和。令(h(i)=f*g.S(i)=sum_i f(i).)

    [sum_i h(i)=sum_{i=1}^n sum_{d|i}f(d)g(frac{n}{d}) ]

    枚举(d:)

    [=sum_{d=1}^n g(d)sum_{i=1}^{frac{n}{d}}f(i)=sum_{d=1}^n g(d)S(frac{n}{d}). ]

    考虑(g(1)S(n))如何求。由上式得:

    [g(1)S(n)=sum_{d=1}^n g(d)S(frac{n}{d})-sum_{d=2}^n g(d)S(frac{n}{d})=sum_{i=1}^n h(i)-sum_{d=2}^n g(d)S(frac{n}{d}) ]

    求出(g(1)S(n))后,除以(g(1))即可得到结果。

    那么,根据上面柿子可以得到应用杜教筛的条件:(g,h)函数的前缀和都很好求。

    (mu)的前缀和

    我们知道,(mu*1=varepsilon.)(f=mu,g=1,h=varepsilon.)

    (varepsilon)的前缀和(=1,g)的前缀和 (=n.)

    从而我们可以在(O(n^{frac{3}{4}}))的时间中求出。

    如果我们线性筛出前 (n^{frac{2}{3}}) 的函数,我们就可以在(O(n^{frac{2}{3}}))的时间中求得结果。

    证明上面(O(n^{frac{3}{4}}))的复杂度:

    求出(S(n))需要(sqrt n)(S(frac{n}{i}))的不同取值。结合数论分块复杂度:

    [O=sum_{i=1}^{sqrt n}sqrt i+sqrt{frac{n}{i}}=n^{frac{3}{4}}. ]

    筛好前(m)个值,上面(sum)上限会变成(frac{n}{m}.)筛出前(n^{frac{2}{3}})即可将时间复杂度降为(O(n^{frac{2}{3}}).)

    (varphi)的前缀和

    (varphi*varepsilon=id,f=varphi,g=varepsilon,h=id.sum id=frac{n*(n+1)}{2}.)同上面求即可。

    上面加起来就是模板.

    (Other)

    (sum varphi(i)·i.)

    (f=sum varphi*i,g=id,h=sum_{d|n} varphi(d)*d*frac{n}{d} =n^2.)同上面求即可。

    上面的模板题中,(varphi)也可以用莫比乌斯反演求出来。

    (sum_{i=1}^n varphi(i)=sum_{i=1}^n sum_{j=1}^i gcd(i,j)=1)

    去掉(j<=i)的限制,即为:

    (sum_{i=1}^n sum_{j=1}^n gcd(i,j)=1=sum_{i=1}^n sum_{j=1}^n sum_{d|gcd(i,j)}mu(i).=sum_{d=1}^n mu(d) (frac{n}{d})^2.)

    求出上面式子,得出它的一半即可。

    模板题代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int MAXN=2e6+10;
    bitset<MAXN+10>vis;
    int p[MAXN+10],cnt,mu[MAXN+10],phi[MAXN+10];
    typedef long long ll;
    void predo(){
    	mu[1]=1;phi[1]=1;
    	for(int i=2;i<=MAXN;++i){
    		if(!vis[i])p[++cnt]=i,phi[i]=i-1,mu[i]=-1;
    		for(int j=1;j<=cnt&&i*p[j]<=MAXN;++j){
    			vis[i*p[j]]=1;
    			if(i%p[j]==0){
    				phi[i*p[j]]=phi[i]*p[j];
    				break;
    			}
    			phi[i*p[j]]=phi[i]*(p[j]-1);
    			mu[i*p[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<=MAXN;++i)mu[i]+=mu[i-1],phi[i]+=phi[i-1];
    }
    map<int,int>M,P;
    ll GetM(int n){
    	if(n<=MAXN)return mu[n];
    	if(M.count(n))return M[n];
    	ll res=1;
    	for(ll l=2,r;l<=n;l=r+1){
    		r=(n/(n/l));
    		res-=(r-l+1)*GetM(n/l);
    	}
    	return M[n]=res;
    }
    ll GetP(int n){
    	if(n<=MAXN)return phi[n];
    	if(P.count(n))return P[n];
    	ll res=(n*(n+1))/2;
    	for(ll l=2,r;l<=n;l=r+1){
    		r=(n/(n/l));
    		res-=(r-l+1)*GetP(n/l);
    	}
    	return P[n]=res;
    }
    signed main(){
    	predo(); 
    	int T;scanf("%lld",&T);while(T--){
    		int x;
    		scanf("%lld",&x);
    		printf("%lld %lld
    ",GetP(x),GetM(x));
    	}
    	return 0;
    }
    
  • 相关阅读:
    使企点QQ来消息时不自动弹出窗口(以避免错过旧的消息和避免正在回复A时自动定位到B从而影响客服效率)
    8款开源聊天软件
    博客园设置皮肤(宽屏等)及选择文本编辑器
    Windows Server 2019 设置使用照片查看器查看图片
    使windows10重启后打开上次的文件夹和程序
    TinyMCE 5 富文本编辑器好
    wordpress 安装 Elementor PRO 插件(破解版)
    无法打印,提示“windows 打印后台处理程序 没有运行”的解决方案
    第一次将代码提交至git error: failed to push some refs to 'https://gitee.com/xxx/test.git'
    git本地和远程的关联问题
  • 原文地址:https://www.cnblogs.com/h-lka/p/13379574.html
Copyright © 2011-2022 走看看