【BZOJ2671】Calc(莫比乌斯反演)(数论分块)

传送门


题解:

十分扯淡的莫反题。

我们要求的是这个东西:

A n s = ∑ i = 1 n ∑ j = 1 i − 1 [ ( i + j ) ∣ i j ] Ans=\sum_{i=1}^n\sum_{j=1}^{i-1}[(i+j)\mid ij] Ans=i=1nj=1i1[(i+j)ij]

直接骚推就行了。

A n s = ∑ d = 1 n ∑ i = 1 n ∑ j = 1 i − 1 [ g c d ( i , j ) = d ] [ ( i + j ) ∣ i j ] = ∑ d = 1 n ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 i − 1 [ g c d ( i , j ) = 1 ] [ ( i + j ) d ∣ i j d 2 ] = ∑ d = 1 n ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 i − 1 [ g c d ( i , j ) = 1 ] [ ( i + j ) ∣ d ] = ∑ i = 1 n ∑ j = 1 i − 1 [ g c d ( i , j ) = 1 ] ∑ d = 1 ⌊ n i ⌋ [ ( i + j ) ∣ d ] = ∑ i = 1 n ∑ j = 1 i − 1 [ g c d ( i , j ) = 1 ] ⌊ n i ( i + j ) ⌋ = ∑ t = 1 n μ ( t ) ∑ i = 1 ⌊ n t ⌋ ∑ j = i + 1 2 i − 1 ⌊ n i j ⌋ \begin{aligned} Ans=&\sum_{d=1}^n\sum_{i=1}^n\sum_{j=1}^{i-1}[gcd(i,j)=d][(i+j)\mid ij]\\ =&\sum_{d=1}^n\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{i-1}[gcd(i,j)=1][(i+j)d\mid ijd^2]\\ =&\sum_{d=1}^n\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{i-1}[gcd(i,j)=1][(i+j)\mid d]\\ =&\sum_{i=1}^n\sum_{j=1}^{i-1}[gcd(i,j)=1]\sum_{d=1}^{\lfloor\frac{n}{i}\rfloor}[(i+j)\mid d]\\ =&\sum_{i=1}^{\sqrt n}\sum_{j=1}^{i-1}[gcd(i,j)=1]\lfloor\frac{n}{i(i+j)}\rfloor\\ =&\sum_{t=1}^{\sqrt n}\mu(t)\sum_{i=1}^{\lfloor\frac{\sqrt n}{t}\rfloor}\sum_{j=i+1}^{2i-1}\lfloor\frac{n}{ij}\rfloor \end{aligned} Ans======d=1ni=1nj=1i1[gcd(i,j)=d][(i+j)ij]d=1ni=1dnj=1i1[gcd(i,j)=1][(i+j)dijd2]d=1ni=1dnj=1i1[gcd(i,j)=1][(i+j)d]i=1nj=1i1[gcd(i,j)=1]d=1in[(i+j)d]i=1n j=1i1[gcd(i,j)=1]i(i+j)nt=1n μ(t)i=1tn j=i+12i1ijn

枚举 t t t,枚举 i i i j j j整除分块即可。

复杂度由积分可知为 O ( n 3 4 ) O(n^\frac{3}{4}) O(n43)


代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const

cs int N=1e5+7;
int p[N],pc;
bool mark[N];
int mu[N];

inline void linear_sieves(int lim){
	mu[1]=1;
	for(int re i=2;i<=lim;++i){
		if(!mark[i])p[++pc]=i,mu[i]=-1;
		for(int re j=1;i*p[j]<=lim;++j){
			mark[i*p[j]]=true;
			if(i%p[j])mu[i*p[j]]=-mu[i];
			else break;
		}
	}
} 

ll n,sqn;ll ans;

inline ll solve(int m,int n){
	ll ans=0;
	for(int re i=1;i<=m;++i){
		ll t=n/i;
		for(int re l=i+1,r;l<(i<<1)&&l<=t;l=r+1){
			r=std::min<int>((i<<1)-1,t/(t/l));
			ans+=(ll)(r-l+1)*(t/l);
		}
	}
	return ans;
}

signed main(){
#ifdef zxyoi
	freopen("calc.in","r",stdin);
#endif
	scanf("%lld",&n);sqn=sqrt(n);linear_sieves(sqn);
	for(int re t=1;t<=sqn;++t)if(mu[t])ans+=mu[t]*solve(sqn/t,n/t/t);
	std::cout<<ans<<"\n";
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值