zoukankan      html  css  js  c++  java
  • ●HDU 5608 function

    题链:

    http://acm.hdu.edu.cn/showproblem.php?pid=5608

    题解:

    莫比乌斯反演,杜教筛

    已知$$N^2-3N+2=sum_{d|N} f(d)$$

    多次询问,给出n,求f的前缀和S(n)。


    把f函数卷上$I(x)=1$

    那么有:

    $$sum_{i=1}^{n}f*l(i)=sum_{i=1}^{n}l(i)S(lfloor frac{n}{i} floor)$$

    所以:

    $$S(n)=sum_{i=1}^{n}f*l(i)-sum_{i=2}^{n}S(lfloor frac{n}{i} floor)$$

    又因为

    $$egin{aligned}
    sum_{i=1}^{n}f*l(i)&=sum_{i=1}^{n}sum_{d|i}f(d)l(frac{i}{d})\
    &=sum_{i=1}^{n}sum_{d|i}f(d)\
    &=sum_{i=1}^{n}(i^2-3i+2)\
    &=frac{n(n+1)(2n+1)}{6}-frac{3n(1+n)}{2}+2n\
    end{aligned}$$

    所以

    $$S(n)=frac{n(n+1)(2n+1)}{6}-frac{3n(1+n)}{2}+2n-sum_{i=2}^{n}S(lfloor frac{n}{i} floor)$$

    到此,就可以直接用杜教筛求解了,不过有点慢。


    我们可以先预处理出前$n^{frac{2}{3}}$个的前缀和

    令$F(N)=N^2-3N+2$,那么F就是f的约数和函数

    (因为$F(N)=sum_{d|N}f(d)$

    所以由莫比乌斯反演可知:

    $$f(N)=sum_{d|N}mu(d)F(frac{N}{d})$$

    然后可以用$O(nlogn)$的复杂度先处理出一些前缀和,

    然后再杜教筛即可。

    代码:

    #include<bits/stdc++.h>
    #define DJM 1000000
    using namespace std;
    const int mod=1000000007;
    struct Hash_Table{
    	#define Hmod 1425367
    	int org[DJM+50],val[DJM+50],nxt[DJM+50],head[Hmod],hnt;
    	Hash_Table(){hnt=1;}
    	void Push(int x,int v){
    		static int u; u=x%Hmod; 
    		org[hnt]=x; val[hnt]=v; nxt[hnt]=head[u]; head[u]=hnt++;
    	}
    	int Find(int x){
    		static int u; u=x%Hmod;
    		for(int i=head[u];i;i=nxt[i])
    			if(org[i]==x) return val[i];
    		return -1;
    	}
    }H;
    int mu[DJM+50],F[DJM+50],f[DJM+50];
    void Sieve(){
    	static bool np[DJM+50];
    	static int prime[DJM+50],pnt;
    	mu[1]=1;
    	for(int i=2;i<=DJM;i++){
    		F[i]=(1ll*i*i-3*i+2+mod)%mod;
    		if(!np[i]) prime[++pnt]=i,mu[i]=-1;
    		for(int j=1;j<=pnt&&i<=DJM/prime[j];j++){
    			np[i*prime[j]]=1;
    			if(i%prime[j]) mu[i*prime[j]]=-mu[i];
    			else break;
    		}
    	}
    	for(int d=1;d<=DJM;d++)
    		for(int i=1;i*d<=DJM;i++)
    			f[i*d]=(1ll*f[i*d]+1ll*mu[d]*F[i]%mod+mod)%mod;
    	for(int i=1;i<=DJM;i++) f[i]=(1ll*f[i]+f[i-1])%mod;
    }
    int DJ_pf(int n){
    	static int inv6=166666668;
    	if(n<=DJM) return f[n];
    	if(H.Find(n)!=-1) return H.Find(n);
    	int ret=(1ll*n*(n+1)%mod*(2*n+1)%mod*inv6%mod-3ll*(1+n)*n/2%mod+2ll*n%mod+mod)%mod;
    	for(int i=2,last;i<=n;i=last+1){
    		last=n/(n/i);
    		ret=(1ll*ret-1ll*(last-i+1)*DJ_pf(n/i)%mod+mod)%mod;
    	}
    	H.Push(n,ret);
    	return ret;
    }
    int main(){
    	Sieve(); int Case,n;
    	for(scanf("%d",&Case);Case;Case--){
    		scanf("%d",&n);
    		printf("%d
    ",DJ_pf(n));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    jQuery 语法
    jQuery 简介
    把数据存储到 XML 文件
    XML 注意事项
    XML DOM (Document Object Model) 定义了访问和操作 XML 文档的标准方法。
    通过 PHP 生成 XML
    XML 命名空间(XML Namespaces)
    XML to HTML
    XMLHttpRequest 对象
    使用 XSLT 显示 XML
  • 原文地址:https://www.cnblogs.com/zj75211/p/8316203.html
Copyright © 2011-2022 走看看