2018蓝桥杯C语言b组国赛 6.矩阵求和 欧拉函数+莫比乌斯反演

版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。 https://blog.csdn.net/qq_42835910/article/details/89607310

第六题

标题:矩阵求和

经过重重笔试面试的考验,小明成功进入 Macrohard 公司工作。 今天小明的任务是填满这么一张表: 表有 n 行 n 列,行和列的编号都从1算起。 其中第 i 行第 j 个元素的值是 gcd(i, j)的平方, gcd 表示最大公约数,以下是这个表的前四行的前四列: 1 1 1 1 1 4 1 4 1 1 9 1 1 4 1 16

小明突然冒出一个奇怪的想法,他想知道这张表中所有元素的和。 由于表过于庞大,他希望借助计算机的力量。

「输入格式」 一行一个正整数 n 意义见题。

「输出格式」 一行一个数,表示所有元素的和。由于答案比较大,请输出模 (10^9 + 7)(即:十亿零七) 后的结果。

「样例输入」 4

「样例输出」 48

「数据范围」 对于 30% 的数据,n <= 1000 存在 10% 的数据,n = 10^5 对于 60% 的数据,n <= 10^6 对于 100% 的数据,n <= 10^7

分析:欧拉函数+莫比乌斯反演

莫比乌斯反演:https://blog.csdn.net/ACdreamers/article/details/8542292

#include <iostream>
using namespace std;
const int N = 1e7+5, MOD = 1e9+7;
long long phi[N], sum[N];
// 欧拉线性筛+求欧拉函数模板 
void euler_table(int n){
	phi[1] = 1;
	for(long long i = 2; i <= n; i++){
		if(!phi[i]){
			for(long long j = i; j <= n; j += i){
				if(!phi[j]) phi[j] = j;
				phi[j] = phi[j]/i*(i-1);
			}	
		}
	}
	sum[1] = 1; //sum表示n阶矩阵中i和j互质的个数。 
	for(int i = 2; i <= n; i++)
		sum[i] = sum[i-1] + phi[i]*2; 
}

int main(int argc, char** argv) {
	int n;
	cin>> n;
	euler_table(n);
	long long ans = 0;
	for(int i = 1; i <= n; i++)
		ans = (ans + sum[n/i]* i%MOD* i%MOD)%MOD;
	cout<< ans << "\n";
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42835910/article/details/89607310