• ●BZOJ 4176 Lucas的数论


    题链:

    http://www.lydsy.com/JudgeOnline/problem.php?id=4176

    题解:

    莫比乌斯反演,杜教筛

    首先有这么一个结论:

    令d(n)表示n的约数的个数(就是题目中的f(n)),则有

    $$d(nm)=sum_{i|n}sum_{j|m}[gcd(i,j)==1]$$

    ●BZOJ 3994 [SDOI2015]约数个数和也用到了这个东西。

    那么就下来接直接进行求ANS的式子的推导:

    $$egin{aligned}
    ANS&=sum_{n=1}^{N}sum_{m=1}^{N}d(nm)\
    &=sum_{n=1}^{N}sum_{m=1}^{N}sum_{i|n}sum_{j|m}[gcd(i,j)==1]\
    &=sum_{n=1}^{N}sum_{m=1}^{N}sum_{i|n}sum_{j|m}sum_{d|gcd(i,j)}mu(d)\
    &=sum_{d=1}^{N}mu(d)sum_{d|i}sum_{d|j}sum_{i|n,nleq N}sum_{j|m,mleq N} 1\
    &=sum_{d=1}^{N}mu(d)(sum_{d|i}lfloor frac{N}{i} floor)^2\
    &=sum_{d=1}^{N}mu(d)(sum_{i=1}^{lfloor frac{N}{d} floor}lfloor frac{N}{id} floor)^2end{aligned}$$

    令$$f(n)=sum_{i=1}^{n}lfloor frac{n}{i} floor$$

    则$$ANS=sum_{d=1}^{N}mu(d)f(lfloor frac{N}{d} floor)^2$$

    这个求ANS的式子是可以分块+杜教筛(求每块$mu$的和)做的,

    同时求f也可以分块求,

    即这是一个块套块。。。

    代码:

    #include<bits/stdc++.h>
    #define DJM /*5623413*/ 1000000
    using namespace std;
    const int mod=1000000007;
    struct Hash_Table{
    	#define Hmod 1425367
    	int org[DJM],val[DJM],nxt[DJM],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 pmu[DJM+50],mu[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++){
    		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 i=1;i<=DJM;i++)
    		pmu[i]=(1ll*mod+pmu[i-1]+mu[i])%mod;
    }
    int f(int n){
    	int ret=0;
    	for(int i=1,last;i<=n;i=last+1){
    		last=n/(n/i);
    		ret=(1ll*ret+1ll*(last-i+1)*(n/i))%mod;
    	}
    	return ret;
    }
    int DJ_pmu(int n){
    	if(n<=DJM) return pmu[n];
    	if(H.Find(n)!=-1) return H.Find(n);
    	int ret=1;
    	for(int i=2,last;i<=n;i=last+1){
    		last=n/(n/i);
    		ret=(1ll*ret+mod-1ll*(last-i+1)*DJ_pmu(n/i)%mod)%mod;
    	}
    	H.Push(n,ret);
    	return ret;
    }
    int main(){
    	Sieve(); int n,ans=0;
    	scanf("%d",&n);
    	for(int d=1,tmp,last;d<=n;d=last+1){
    		last=n/(n/d); tmp=f(n/d);
    		tmp=1ll*tmp*tmp%mod;
    		ans=(1ll*ans+(1ll*DJ_pmu(last)-DJ_pmu(d-1)+mod)%mod*tmp%mod)%mod;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

     

  • 相关阅读:
    【DUBBO】dubbo架构详解(转载)
    【数据库】sql连表查询
    第十三章 三种非对称加密算法总结
    第十二章 非对称加密算法-RSA
    第十一章 非对称加密算法--DH
    第十章 五种对称加密算法总结
    第九章 对称加密算法--IDEA
    第八章 对称加密算法--AES
    第七章 对称加密算法--DES
    第六章 三大消息摘要算法总结
  • 原文地址:https://www.cnblogs.com/zj75211/p/8316057.html
Copyright © 2020-2023  润新知