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;
    }
    
  • 相关阅读:
    Scala 并发编程
    rsyslog start with
    rsyslog start with
    logrotate 日志清理后 rsyslog中断问题
    logrotate 日志清理后 rsyslog中断问题
    logrotate 清理tomcat日志
    rsyslog 传输mysql 日志
    rsyslog 传输mysql 日志
    NYOJ833
    NYOJ65
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8350374.html
Copyright © 2011-2022 走看看