zoukankan      html  css  js  c++  java
  • [模板]杜教筛

    杜教筛模板题。
    求欧拉函数和莫比乌斯函数的前缀和。
    鼻炎犯了,证明改天写。。。。
    (大佬们看看有没有错啊。。。为啥跑的这么慢。。。)

    #include <iostream>
    #include <cstdio>
    #include <map>
    using namespace std;
    typedef long long ll;
    const int N=7000000;
    int n;
    map<int,ll>ph,mu;
    int prime[N>>3],tot;ll phi[N],miu[N];
    bool vis[N];
    void init() {
        miu[1]=phi[1]=1;
        for(int i=2;i<=N-5;i++) {
            if(!vis[i]) prime[++tot]=i,miu[i]=-1,phi[i]=i-1;
            for(int j=1;j<=tot&&prime[j]*i<=N-5;j++) {
                vis[i*prime[j]]=1;
                if(i%prime[j]==0) {phi[i*prime[j]]=phi[i]*prime[j];break;}
                phi[i*prime[j]]=phi[i]*phi[prime[j]];miu[i*prime[j]]=-miu[i];
            }
        }
        for(int i=1;i<=N-5;i++) phi[i]+=phi[i-1],miu[i]+=miu[i-1];
    }
    ll solvephi(int x) {
        if(x<=N-5) return phi[x];
    	if(ph.count(x)) return ph[x];
    	ll ans=1ll*x*(x+1)/2;
    	for(int i=2,nxti;i<=x;i=nxti) {
    		nxti=x/(x/i)+1;
    		ans-=(nxti-i)*solvephi(x/i);
    	}
    	return ph[x]=ans;
    }
    ll solvemiu(int x) {
        if(x<=N-5) return miu[x];
    	if(mu.count(x)) return mu[x];
    	ll ans=1;
    	for(int i=2,nxti;i<=x;i=nxti) {
    		nxti=x/(x/i)+1;
    		ans-=(nxti-i)*solvemiu(x/i);
    	}
    	return mu[x]=ans;
    }
    int T;
    int main() {
    	init();
    	cin>>T;
    	while(T--){
    	cin>>n;
    	cout<<solvephi(n)<<' '<<solvemiu(n)<<endl;
    	}
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    使用GitHub+hexo搭建个人独立博客
    HDU 3038
    POJ 1417
    HDU 1213
    ZOJ 3781
    ZOJ 3780
    ZOJ 3777
    HDU 3045
    HDU 3480
    POJ 1180
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9607590.html
Copyright © 2011-2022 走看看