zoukankan      html  css  js  c++  java
  • HDU.5608.function(杜教筛)

    (Description)

      (n^2-3n+2=sum_{d|n}f(d))
      求(sum_{i=1}^nf(i) mod 10^9+7).

    (Solution)

      参考.
      设(g(n)=n^2-3n+2),那么(f*I=g)
      如果狄利克雷卷积中左边的一个函数是待求前缀和的,而另外两个函数的前缀和比较好计算,那么就可以简化计算过程。
      像之前一样,试着计算一下(sum_{i=1}^ng(i)): $$sum_{i=1}^ng(i)=sum_{i=1}^nsum_{d|i}f(d)=sum_{i=1}^nsum_{d=1}^{lfloorfrac{n}{i} floor}f(d)$$
      而

    [egin{aligned}sum_{i=1}^ng(i)&=sum_{i=1}^ni^2-3sum_{i=1}^ni+2n=frac{n(n+1)(2n+1)}{6}-frac{3n(n+1)}{2}+2n\&=frac{n(n-1)(n-2)}{3}end{aligned} ]

      (upd:好久没用,不知道博客园怎么改的Latex,不知道哪错了,复制到别的上看叭)
      step2同之前,就是换做考虑因数贡献的值(sum_{i=1}^nsum_{d|i}f(frac{i}{d})=sum_{d=1}^nsum_{i=1}^{lfloorfrac{n}{d} floor}f(i))
      这样(sum_{i=1}^nf(i)=frac{n(n-1)(n-2)}{3}-sum_{i=2}^nsum_{d=1}^{lfloorfrac{n}{i} floor}f(d))
      预处理就用线筛和莫比乌斯反演 暴力枚举约数。(枚举到多少最适合我也不知道==经过二分,发现确实是6e5比较好...)

    /*
    注意:有μ所以会有负的!不能用Mod(x),也不能直接取模(先+mod) 
    */
    #include<map>
    #include<cstdio>
    #include<cctype>
    #define gc() getchar()
    typedef long long LL;
    const int N=6e5+1,mod=1e9+7;
    
    int n,mu[N+3],P[N>>1],f[N+3],cnt;
    bool Not_P[N+3];
    std::map<int,int> ref;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    #define Mod(x) x>=mod?x-=mod:0
    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=1;i<N;++i)
    	{
    		int t=((LL)i*i%mod-3*i%mod+2+mod)%mod;
    		for(int j=i;j<N;j+=i)
    			(f[j]+=mu[j/i]*t%mod)%=mod;
    //		WA:	f[j]+=mu[j/i]*t%mod, Mod(f[j]);
    	}
    	for(int i=1;i<N;++i) f[i]=((f[i]+f[i-1])%mod+mod)%mod;
    //WA:for(int i=1;i<N;++i) sum[i]=sum[i-1]+f[i]%mod, Mod(sum[i]);
    }
    int FP(LL x,int k)
    {
    	LL t=1;
    	for(;k;k>>=1,x=x*x%mod)
    		if(k&1) t=t*x%mod;
    	return t;
    }
    const int inv3=FP(3,mod-2);//333333336
    int Calc(int n)
    {
    	if(n<N) return f[n];
    	if(ref.count(n)) return ref[n];
    	int ans=(1LL*n*(n-1)%mod*(n-2)%mod*inv3%mod);
    	for(int las,i=2;i<=n;i=las+1)
    		las=n/(n/i),ans-=1ll*(las-i+1)*Calc(n/i)%mod,ans%=mod;
    	return ref[n]=(ans+mod)%mod;
    }
    
    int main()
    {
    	Init();
    	for(int t=read();t--;)
    	{
    		int n=read();
    		printf("%d
    ",Calc(n));
    	}
    	return 0;
    }
    
  • 相关阅读:
    POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram【堆栈】
    CCF201612-4 压缩编码(100分)
    CCF201612-4 压缩编码(100分)
    HDU1201 18岁生日【日期计算】
    HDU1201 18岁生日【日期计算】
    CCF201403-1 相反数(解法二)(100分)
    CCF201403-1 相反数(解法二)(100分)
    POJ3752 字母旋转游戏【水题】
    POJ3752 字母旋转游戏【水题】
    HDU1869 六度分离
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8352820.html
Copyright © 2011-2022 走看看