• ●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;
    }
    

      

  • 相关阅读:
    实现 HTML页面 Table 标签分页打印
    windows定时休眠设置
    python画树
    anaconda历史版本
    枚举
    is 与 as 运算符举例
    Microsoft.ACE.OLEDB.12.0报错解决方法
    winform一个带自动完成功能的TextBox
    DWZ中整合第三方jQuery(kit日历控件)插件
    asp.net 使用NPOI,泛型反射,XML导入导出excel
  • 原文地址:https://www.cnblogs.com/zj75211/p/8316203.html
Copyright © 2020-2023  润新知