Codeforces Round #818 (Div. 2)E. Madoka and The Best University

Codeforces Round #818 (Div. 2)

E. Madoka and The Best University

题目要求\(\sum lcm(c,gcd(a,b))\),其中a,b,c满足\(a+b+c=n\)

首先\(gcd(a,b)=gcd(a,a+b)=gcd(a,n-c)\)

我们记\(d=gcd(a,n-c)\)那么答案就是求\(\sum lcm(c,d)*cnt\)

cnt代表有多少个a,b满足\(gcd(a,b)=d\)

我们可以枚举c,再枚举n-c的因子d

然后我们考虑有多少个a,b会让\(gcd(a,b)=d\)

因为\(gcd(a,b)=gcd(a,n-c)=d\)

那么\(gcd(\frac{a}{d},\frac{n-c}{d})=1\)

也就是求有多少个\(\frac{a}{d}\)\(\frac{n-c}{d}\)互质,那么就是\(\phi(\frac{n-c}{d})\)

AC代码:

#include<cstdio>
#define M 100005
#define P 1000000007
bool mark[M];
int Prime[M],sz;
int ph[M];
void Init(){
	for(int i=2;i<M;i++){
		if(!mark[i]){
			Prime[++sz]=i;
			ph[i]=i-1;
		}
		for(int j=1;j<=sz&&i*Prime[j]<M;j++){
			mark[i*Prime[j]]=true;
			if(i%Prime[j]==0){
				ph[i*Prime[j]]=Prime[j]*ph[i];
			}else ph[i*Prime[j]]=ph[i]*(Prime[j]-1);
		}
	}
}
int gcd(int a,int b){
	if(!b)return a;
	return gcd(b,a%b);
}
long long lcm(int a,int b){
	return 1ll*a*b/gcd(a,b);
}
int main(){
	Init();
	int n;
	scanf("%d",&n);
	long long ans=0;
	for(int c=1;c<=n-2;c++){
		for(int d=1;d*d<=n-c;d++){
			if((n-c)%d!=0)continue;
			ans=(ans+1ll*lcm(c,d)*ph[(n-c)/d])%P;
			if(d*d!=n-c){
				ans=(ans+1ll*lcm(c,(n-c)/d)*ph[d])%P;
			}
		}
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2022-09-04 14:07  IceLoging  阅读(52)  评论(0)    收藏  举报