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;
    }
    
  • 相关阅读:
    MSSQL大量数据时,建立索引或添加字段后保存更改超时该这么办
    POJ 3261 Milk Patterns (后缀数组)
    POJ 1743 Musical Theme (后缀数组)
    HDU 1496 Equations (HASH)
    694. Distinct Substrings (后缀数组)
    POJ 1222 EXTENDED LIGHTS OUT (枚举 或者 高斯消元)
    POJ 1681· Painter's Problem (位压缩 或 高斯消元)
    POJ 1054 The Troublesome Frog (hash散列)
    HDU 1716 排列2
    HDU 4405 Aeroplane chess (概率DP & 期望)
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8350374.html
Copyright © 2011-2022 走看看