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

      

  • 相关阅读:
    FZU 2150 Fire Game
    POJ 3414 Pots
    POJ 3087 Shuffle'm Up
    POJ 3126 Prime Path
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    字符数组
    HDU 1238 Substing
    欧几里德和扩展欧几里德详解 以及例题CodeForces 7C
    Codeforces 591B Rebranding
  • 原文地址:https://www.cnblogs.com/zj75211/p/8316203.html
Copyright © 2011-2022 走看看