UVA 11426

25 篇文章 0 订阅

UVA 11426(欧拉函数)

∑ i = 2 N − 1 ∑ j = i + 1 N g c d ( i , j ) \sum_{i=2}^{N-1}\sum_{j=i+1}^Ngcd(i,j) i=2N1j=i+1Ngcd(i,j)

一开始想过用莫比乌斯反演做…然而做不出来。

解:
∑ i = 1 N − 1 ∑ j = i + 1 N g c d ( i , j ) = ∑ i = 2 N ∑ j = 1 i − 1 g c d ( i , j ) \sum_{i=1}^{N-1}\sum_{j=i+1}^Ngcd(i,j)=\sum_{i=2}^N\sum_{j=1}^{i-1}gcd(i,j) i=1N1j=i+1Ngcd(i,j)=i=2Nj=1i1gcd(i,j)
g c d ( i , j ) = d gcd(i,j)=d gcd(i,j)=d等价于 g c d ( i d , j d ) = 1 gcd(\frac{i}{d},\frac{j}{d})=1 gcd(di,dj)=1
既然直接求 g c d ( i , j ) gcd(i,j) gcd(i,j)比较难,那么我们是否可以求满足 [ g c d ( i , j ) = = 1 ] [gcd(i,j)==1] [gcd(i,j)==1] ( i , j ) , j < i (i,j),j<i (i,j),j<i,这样每对 ( k ∗ i , k ∗ j ) (k*i,k*j) (ki,kj)对答案的贡献就是 k k k

因为 j j j严格小于 i i i g c d ( i , j ) = = 1 gcd(i,j)==1 gcd(i,j)==1的个数就是 ϕ ( i ) \phi(i) ϕ(i)
现在考虑 k k k的取值范围,因为要满足 1 ≤ j < i ≤ n 1\le j<i\le n 1j<in,所以易得 k k k的取值范围是 1 ≤ k ≤ ⌊ n i ⌋ 1\le k\le \lfloor\frac{n}{i}\rfloor 1kin

那么每个 i i i对答案的贡献就是 1 + 2 + . . . + ⌊ n i ⌋ 1+2+...+\lfloor\frac{n}{i}\rfloor 1+2+...+in

∑ i = 1 N − 1 ∑ j = i + 1 N g c d ( i , j ) = ∑ i = 2 N ∑ j = 1 i − 1 g c d ( i , j ) = ∑ i = 2 N ϕ ( i ) ( 1 + ⌊ n i ⌋ ) ⌊ n i ⌋ 2 \begin{aligned} \sum_{i=1}^{N-1}\sum_{j=i+1}^Ngcd(i,j)&=\sum_{i=2}^N\sum_{j=1}^{i-1}gcd(i,j)\\ &=\sum_{i=2}^N\phi(i)\frac{(1+\lfloor\frac{n}{i}\rfloor)\lfloor\frac{n}{i}\rfloor}{2} \end{aligned} i=1N1j=i+1Ngcd(i,j)=i=2Nj=1i1gcd(i,j)=i=2Nϕ(i)2(1+in)in

时间复杂度 O ( t n ) + O ( N ) O(tn)+O(N) O(tn)+O(N)

#include<bits/stdc++.h>
using namespace std;
const int max_n=4e6+5;
int prime[max_n];
int vis[max_n];
int cnt=0;
int e[max_n];
void init(void)
{
	for(int i=2;i<max_n;i++)
	{
		if(!vis[i]){
			prime[cnt++]=i;
			e[i]=i-1;
		}
		for(int j=0;j<cnt&&i*prime[j]<max_n;j++)
		{
			vis[i*prime[j]]=1;
			if(i%prime[j]==0){
				e[i*prime[j]]=e[i]*prime[j];
				break;
			} 
			e[i*prime[j]]=e[i]*e[prime[j]];
		}
	}
}
int main(void)
{
	int n;
	init();
	while(~scanf("%d",&n)&&n)
	{
		long long ans=0,t;
		for(int i=2;i<=n;i++)
		{
			t=n/i;
			t=(1+t)*t/2;
			ans+=1ll*e[i]*t;
		}
		printf("%lld\n",ans);
	}
}
//10
//100
//200000
//0
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值