acm-(数论、好题、莫比乌斯反演、推式子)51nod 1222 最小公倍数计数

题面
传送门
f ( n ) = ∑ i = 1 n ∑ j = 1 n [ l c m ( i , j ) ≤ n ] f(n)=\sum_{i=1}^{n}\sum_{j=1}^n[lcm(i,j)\le n] f(n)=i=1nj=1n[lcm(i,j)n],题目让我们求的其实是 ∑ i = 1 b ∑ j = 1 i [ l c m ( i , j ) ≤ b ] − ∑ i = 1 a − 1 ∑ j = 1 i [ l c m ( i , j ) ≤ a − 1 ] \sum_{i=1}^b\sum_{j=1}^i[lcm(i,j)\le b]-\sum_{i=1}^{a-1}\sum_{j=1}^i[lcm(i,j)\le a-1] i=1bj=1i[lcm(i,j)b]i=1a1j=1i[lcm(i,j)a1],也就是说要求出 ∑ i = 1 n ∑ j = 1 i [ l c m ( i , j ) ≤ b ] \sum_{i=1}^n\sum_{j=1}^i[lcm(i,j)\le b] i=1nj=1i[lcm(i,j)b],但这个式子不太方便我们反演,它其实就是 1 2 ( ∑ i = 1 n ∑ j = 1 n [ l c m ( i , j ) ≤ n ] + ∑ i = 1 n [ l c m ( i , i ) ≤ n ] ) = f ( n ) + n 2 \frac 12(\sum_{i=1}^n\sum_{j=1}^n[lcm(i,j)\le n]+\sum_{i=1}^n[lcm(i,i)\le n])=\frac {f(n)+n}2 21(i=1nj=1n[lcm(i,j)n]+i=1n[lcm(i,i)n])=2f(n)+n,因此我们下面考虑如何求出 f ( n ) f(n) f(n)

f ( n ) = ∑ i = 1 n ∑ j = 1 n [ l c m ( i , j ) ≤ n ] = ∑ k = 1 n ∑ i = 1 n ∑ j = 1 n [ i j k ≤ n ] [ g c d ( i , j ) = k ] = ∑ k = 1 n ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ n k ⌋ [ i j k ≤ n ] ∑ d ∣ i , d ∣ j μ ( d ) = ∑ k = 1 n ∑ i = 1 n ∑ j = 1 n [ i j k ≤ n ] ∑ d ∣ i , d ∣ j μ ( d ) = ∑ d = 1 n μ ( d ) ∑ k = 1 n ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ [ i j k ≤ ⌊ n d 2 ⌋ ] = ∑ d = 1 ⌊ n ⌋ μ ( d ) ∑ k = 1 ⌊ n d 2 ⌋ ∑ i = 1 ⌊ n d 2 ⌋ ∑ j = 1 ⌊ n d 2 ⌋ [ i j k ≤ ⌊ n d 2 ⌋ ] = ∑ d = 1 ⌊ n ⌋ μ ( d ) g ( ⌊ n d 2 ⌋ ) . . . . . 令 g ( n ) = ∑ k = 1 n ∑ i = 1 n ∑ j = 1 n [ i j k ≤ n ] \begin{aligned} f(n)&=\sum_{i=1}^n\sum_{j=1}^n[lcm(i,j)\le n]\\ &=\sum_{k=1}^n\sum_{i=1}^n\sum_{j=1}^n[\frac {ij}k\le n][gcd(i,j)=k]\\ &=\sum_{k=1}^n\sum_{i=1}^{\lfloor \frac nk\rfloor}\sum_{j=1}^{\lfloor\frac nk\rfloor}[ijk\le n]\sum_{d\mid i,d\mid j}\mu(d)\\ &=\sum_{k=1}^n\sum_{i=1}^{n}\sum_{j=1}^{n}[ijk\le n]\sum_{d\mid i,d\mid j}\mu(d)\\ &=\sum_{d=1}^n\mu(d)\sum_{k=1}^n\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}[ijk\le \lfloor\frac n{d^2}\rfloor]\\ &=\sum_{d=1}^{\lfloor\sqrt n\rfloor}\mu(d)\sum_{k=1}^{\lfloor \frac n{d^2}\rfloor}\sum_{i=1}^{\lfloor\frac n{d^2}\rfloor}\sum_{j=1}^{\lfloor\frac n{d^2}\rfloor}[ijk\le \lfloor\frac n{d^2}\rfloor]\\ &=\sum_{d=1}^{\lfloor\sqrt n\rfloor}\mu(d)g(\lfloor\frac n{d^2}\rfloor).....令g(n)=\sum_{k=1}^n\sum_{i=1}^n\sum_{j=1}^n[ijk\le n] \end{aligned} f(n)=i=1nj=1n[lcm(i,j)n]=k=1ni=1nj=1n[kijn][gcd(i,j)=k]=k=1ni=1knj=1kn[ijkn]di,djμ(d)=k=1ni=1nj=1n[ijkn]di,djμ(d)=d=1nμ(d)k=1ni=1dnj=1dn[ijkd2n]=d=1n μ(d)k=1d2ni=1d2nj=1d2n[ijkd2n]=d=1n μ(d)g(d2n).....g(n)=k=1ni=1nj=1n[ijkn]
现在考虑如何求 g ( n ) g(n) g(n),根据对称性,我们假设 k ≤ i ≤ j k\le i\le j kij,于是容易确定 k ∈ [ 1 , ⌊ n 1 3 ⌋ ] , i ∈ [ k , ⌊ n k ⌋ ] , j ∈ [ i , ⌊ n i k ⌋ ] k\in[1,\lfloor n^{\frac 13}\rfloor],i\in[k,\lfloor \sqrt{\frac nk}\rfloor],j\in[i,\lfloor\frac n{ik}\rfloor] k[1,n31],i[k,kn ],j[i,ikn],枚举量大概是 O ( n + n 2 + n 3 + . . . + n n 1 3 ) = O ( ∫ 1 n 1 3 n x   d x ) = O ( n 2 3 ) O(\sqrt n+\sqrt{\frac n2}+\sqrt{\frac n3}+...+\sqrt{\frac n{n^{\frac 13}}})=O(\int_{1}^{n^{\frac 13}} \sqrt{\frac nx}\, {\rm d}x)=O(n^{\frac 23}) O(n +2n +3n +...+n31n )=O(1n31xn dx)=O(n32),然后枚举的时候分三种情况计算贡献即可 k < i < j k<i<j k<i<j时要算6, k = i < j 或 k < i = j k=i<j或k<i=j k=i<jk<i=j时要算3, k = i = j k=i=j k=i=j时要算1。

总复杂度的话就是 O ( ∑ d = 1 n ( n d 2 ) 2 3 ) = O ( n 2 3 ) O(\sum_{d=1}^{\sqrt n}{(\frac n{d^2})}^{\frac 23})=O(n^{\frac 23}) O(d=1n (d2n)32)=O(n32),你可以理解为杜教筛外面套了个 O ( n ) O(\sqrt n) O(n )的分块,因此复杂度不变。

int prim[maxn],tot,mu[maxn];
bool flag[maxn];

void init(int n){
	mu[1]=1;
	FOR(i,2,n+1){
		if(!flag[i])prim[tot++]=i,mu[i]=-1;
		for(register int j=0;j<tot && prim[j]*i<=n;++j){
			flag[i*prim[j]]=1;
			if(i%prim[j]==0)break;
			mu[i*prim[j]]=-mu[i];
		}
	}
}
ll get(ll n){
	register int limt1 = pow(n,1.0/3.0),limt2;
	register ll ans=0,c,up;
	while(1ll*limt1*limt1*limt1<=n)limt1++;
	while(1ll*limt1*limt1*limt1>n)limt1--;
	FOR(k,1,limt1+1){
		c=n/k;
		limt2=(int)(sqrt(c)+0.5);
		FOR(i,k,limt2+1){
			up=c/i;
			if(up<i)break;
			if(i==k){
				ans+=3ll*(up-i)+1ll;
			}else{
				ans+=6ll*(up-i)+3ll;
			}
		}
	}
	return ans;
}
ll cal(ll n){
	if(!n)return 0;
	register int limt = sqrt(n);
	register ll ans=0;
	FOR(i,1,limt+1)ans+=mu[i]*get(n/(1ll*i*i));
	return (ans+n)>>1;
}
int main(){
	ll a,b;
	rd(&a,&b);
	init((int)sqrt(b));
	wrn(cal(b)-cal(a-1));
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值