• [51Nod 1244]


    [51Nod 1244] - 莫比乌斯函数之和

    i=1Nμ(i)sum_{i=1}^Nμ(i)
    开推
    dnμ(d)=[n==1]sum_{d|n}mu(d)=[n==1]
    移项
    μ(d)=[n==1]dn,d<nμ(d)S(N)=i=1Nμ(i)=i=1N([i==1]di,d<iμ(d))=1i=1Ndi,d<iμ(d)mu(d)=[n==1]-sum_{d|n,d<n}mu(d) ewline herefore S(N)=sum_{i=1}^Nμ(i)=sum_{i=1}^N([i==1]-sum_{d|i,d<i}mu(d)) ewline =1-sum_{i=1}^Nsum_{d|i,d<i}mu(d) ewline
    此处是杜教筛的精髓,也是整除分块优化的精髓(或者说是转换方法),枚举i是d的多少倍
    S(N)=1id=2Nd=1,1<idNidμ(d)S(N)=1-sum_{{lfloor{frac id} floor} =2}^Nsum_{d=1,1<{lfloor{frac id} floor}}^{lfloor frac N{lfloor{frac id} floor} floor}mu(d)
    k=idk={lfloor{frac id} floor},则有
    S(N)=1k=2Nd=1Nkμ(d)=1k=2NS(Nk)S(N)=1-sum_{k=2}^Nsum_{d=1}^{lfloor frac Nk floor}mu(d) =1-sum_{k=2}^NS({lfloor frac Nk floor})
    那么就可以用线性筛出前面一部分,再整除分块优化递归处理
    杜教筛无预处理的时间复杂度是Θ(n34)Theta(n^{frac 34})
    预处理一定范围内的答案后就能降到Θ(n23)Theta(n^{frac 23})
    然而我们此处并不需要多小的时间复杂度…随便处理一个10710^7就能过了

    AC code
    #include <cstdio>
    #include <map>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define LL long long
    const int MAXP = 1e7+1;
    
    int Prime[MAXP/10], Cnt, mu[MAXP], sum[MAXP];
    bool IsnotPrime[MAXP];
    map<LL,int>S;
    void init(int N)
    {
    	mu[1] = 1;
    	for(int i = 2; i <= N; ++i)
    	{
    		if(!IsnotPrime[i]) Prime[++Cnt] = i, mu[i] = -1;
    		for(int j = 1; j <= Cnt && i * Prime[j] <= N; ++j)
    		{
    			IsnotPrime[i * Prime[j]] = 1;
    			if(i % Prime[j] == 0) { mu[i * Prime[j]] = 0; break; }
    			mu[i * Prime[j]] = -mu[i];
    		}
    	}
    	for(int i = 1; i <= N; i++) sum[i] = sum[i-1] + mu[i];
    }
    
    inline int solve(LL N)
    {
    	if(N < MAXP) return sum[N];
    	if(S.count(N)) return S[N];//记忆化,其实此处可以Hash或者用
    	int ret = 1;
    	for(LL i = 2, j; i <= N; i=j+1)
    	{
    		j = N/(N/i);
    		ret -= (j-i+1) * solve(N/i);
    	}
    	return S[N] = ret;
    }
    
    int main ()
    {
        LL n, m; init(MAXP-1);
        scanf("%lld%lld", &n, &m);
        printf("%d
    ", solve(m)-solve(n-1));
    }
    

    [51Nod 1239] - 欧拉函数之和

    i=1Nφ(i)sum_{i=1}^Nφ(i)
    开推,有
    dnφ(d)=n sum_{d|n}φ(d)=n
    移项
    φ(n)=ndn,d&lt;nφ(d)S(N)=i=1N(idi,d&lt;iφ(d))=N(N+1)2i=1Ndi,d&lt;iφ(d)=N(N+1)2id=2Nd=1Nidφ(d) φ(n)=n-sum_{d|n,d&lt;n}φ(d) ewline herefore S(N)=sum_{i=1}^N(i-sum_{d|i,d&lt;i}φ(d)) ewline =frac{N*(N+1)}2-sum_{i=1}^Nsum_{d|i,d&lt;i}φ(d) ewline =frac{N*(N+1)}2-sum_{{lfloorfrac id floor}=2}^Nsum_{d=1}^{{lfloorfrac N{{lfloorfrac id floor}} floor}}φ(d) ewline
    k=idk={lfloor{frac id} floor},则有
    S(N)=N(N+1)2k=2Nd=1Nkφ(d)=N(N+1)2k=2NS(Nk) S(N)=frac{N*(N+1)}2-sum_{k=2}^Nsum_{d=1}^{{lfloorfrac Nk floor}}φ(d) ewline =frac{N*(N+1)}2-sum_{k=2}^NS({lfloorfrac Nk floor}) ewline
    然后…就没有了.像上一道题一样处理就完了

    AC Code
    #include <cstdio>
    #include <map>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define LL long long
    const int MAXP = 5e6 + 1;
    const int mod = 1e9 + 7;
    const int inv2 = 500000004;
    
    int Prime[MAXP/10], Cnt, phi[MAXP];
    LL sum_phi[MAXP];
    bool IsnotPrime[MAXP];
    
    void init(int N)
    {
    	phi[1] = 1;
    	for(LL i = 2; i <= N; ++i)
    	{
    		if(!IsnotPrime[i]) Prime[++Cnt] = i, phi[i] = i-1;
    		for(LL j = 1; j <= Cnt && i * Prime[j] <= N; ++j)
    		{
    			IsnotPrime[i * Prime[j]] = 1;
    			if(i % Prime[j] == 0)
    			{
    				phi[i * Prime[j]] = phi[i] * Prime[j];
    				break;
    			}
    			phi[i * Prime[j]] = phi[i] * (Prime[j]-1);
    		}
    	}
    	for(int i = 1; i <= N; i++)
    		sum_phi[i] = ((sum_phi[i-1] + phi[i]) % mod + mod) % mod;
    }
    map<LL, LL> S_phi;
    inline LL solve_phi(LL N)
    {
    	if(N < MAXP) return sum_phi[N];
    	if(S_phi.count(N)) return S_phi[N];
    	LL ret = (N%mod + 1) * (N%mod) % mod * inv2 % mod;
    	for(LL i = 2, j; i <= N; i=j+1)
    	{
    		j = N/(N/i);
    		ret = (ret - (j-i+1) % mod * solve_phi(N/i) % mod) % mod;
    	}
    	return S_phi[N] = ((ret + mod) % mod);
    }
    int main ()
    {
    	init(MAXP-1); LL n;
    	scanf("%lld", &n);
    	printf("%lld
    ", solve_phi(n));
    }
    
  • 相关阅读:
    JDBC批量删除某一用户下的触发器
    DWZ框架修改默认主页(转)
    JSP页面中的js方法遍历后台传来的自定义对象的List
    JDBC获取表注释
    你的显示方式安全么?JSTL中c:out标签介绍
    tomcat启动报错
    PPP协议体系的实现
    Linux下的虚拟Bridge实现
    三皇五帝
    贴近原理层的科技发展
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039464.html
Copyright © 2020-2023  润新知