zoukankan      html  css  js  c++  java
  • 51Nod.1244.莫比乌斯函数之和(杜教筛)

    题目链接


    map:

    //杜教筛
    #include<map>
    #include<cstdio>
    typedef long long LL;
    const int N=5e6;
    
    int mu[N+3],P[N+3],cnt;
    bool Not_P[N+3];
    std::map<LL,LL> sum;
    //std::map<LL,LL>::iterator it;
    
    void Init()
    {
    	mu[1]=1;
    	for(int i=2;i<N;++i)
    	{
    		if(!Not_P[i]) P[++cnt]=i,mu[i]=-1;
    		for(int j=1;j<=cnt&&i*P[j]<N;++j)
    		{
    			Not_P[i*P[j]]=1;
    			if(!(i%P[j])) {mu[i*P[j]]=0; break;}
    			mu[i*P[j]]=-mu[i];
    		}
    	}
    	for(int i=2;i<N;++i) mu[i]+=mu[i-1];
    }
    LL Calc(LL n)
    {
    	if(n<N) return mu[n];
    //	if((it=sum.find(n))!=sum.end()) return it->second;//效率是几乎一样的
    	if(sum.count(n)) return sum[n];
    	LL ans=1;
    	for(LL nxt,i=2;i<=n;i=nxt+1)
    		nxt=n/(n/i),ans-=(nxt-i+1)*Calc(n/i);
    	return sum[n]=ans;
    }
    
    int main()
    {
    	Init();
    	LL a,b;scanf("%lld%lld",&a,&b);
    	printf("%lld",Calc(b)-Calc(a-1));
    
    	return 0;
    }
    

    数组:(使用数组这个trick存的话 对于多组询问就要重新计算了)
    但是据(rqy)说map实际用到的次数并不多,所以多次询问还是直接用map吧。
    //比map还要慢一点

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long LL;
    const int N=5e6;
    
    int mu[N+3],P[N+3],cnt;
    LL sum2[15000],Max;
    bool Not_P[N+3];
    
    void Init()
    {
    	mu[1]=1;
    	for(int i=2;i<Max;++i)
    	{
    		if(!Not_P[i]) P[++cnt]=i,mu[i]=-1;
    		for(int j=1;j<=cnt&&i*P[j]<Max;++j)
    		{
    			Not_P[i*P[j]]=1;
    			if(!(i%P[j])) {mu[i*P[j]]=0; break;}
    			mu[i*P[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<Max;++i) mu[i]+=mu[i-1];
    }
    const int EQU=-2333333;
    LL Calc(LL n,LL mx)
    {
    	if(n<Max) return mu[n];
    	if(sum2[mx/n]!=EQU) return sum2[mx/n];
    	LL ans=1;
    	for(LL nxt,i=2;i<=n;i=nxt+1)
    		nxt=n/(n/i),ans-=(nxt-i+1)*Calc(n/i,mx);
    	return sum2[mx/n]=ans;
    }
    
    int main()
    {
    	LL a,b;scanf("%lld%lld",&a,&b);
    //	printf("%.3lf %.3lf
    ",pow(a,0.667),pow(b,0.667));
    	Max=pow(b,0.667), Init();
    	std::fill(sum2,sum2+15000,EQU); LL ans1=Calc(b,b);
    	std::fill(sum2,sum2+15000,EQU); LL ans2=Calc(a-1,a-1);
    	printf("%lld",ans1-ans2);
    
    	return 0;
    }
    
  • 相关阅读:
    通过HTTP发包工具了解HTTP协议
    Oracle之数据库安全
    SQL注入深入剖析
    apache中如何调用CGI脚本
    fastcgi php-cgi与php-fpm区别和之间的关系
    使用PHPExcel实现Excel文件的导入和导出(模板导出)
    学会数据库读写分离、分表分库
    框架Thinkphp5 简单的实现行为 钩子 Hook
    php文件下载
    PHP为JSON数据的API返回空数组或者空对象
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8350374.html
Copyright © 2011-2022 走看看