UVA11426 GCD - Extreme (II) —— 欧拉函数
2024-09-04 12:46:00
题目链接:https://vjudge.net/problem/UVA-11426
题意:
求 ∑ gcd(i,j),其中 1<=i<j<=n 。
题解:
1. 欧拉函数的定义:满足 0<x<n 且 gcd(x,n) = 1 的x有euler[n]个。
2. 可以推论出:满足 0<2*x<2*n 且 gcd(2*x,2*n) = 2 的2*x同样有euler[n]个,推向一般:满足 0<k*x<k*n 且 gcd(k*x,k*n) = k 的k*x有euler[n]个。解释:其实就是对于n来说,在1~n-1内与它互质的数都乘上相应的倍数,同时n也乘上相应的倍数,因而他们的最大公约数也为乘上的倍数,但不管如何,个数没有改变,仍为euler[n]个,只不过是他们的值“放大”了罢。
3. 有了上述结论,就可以枚举每个欧拉函数euler[n]和系数k,然后进行统计。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; int euler[MAXN];
void getEuler()
{
memset(euler, , sizeof(euler));
euler[] = ;
for(int i = ; i<MAXN; i++) if(!euler[i]) {
for(int j = i; j<MAXN; j += i)
{
if(!euler[j]) euler[j] = j;
euler[j] = euler[j]/i*(i-);
}
}
} LL sum[MAXN];
void init()
{
getEuler();
memset(sum, , sizeof(sum));
for(int i = ; i<MAXN; i++) // 枚举“单位”欧拉数
for(int k = ; i*k<MAXN; k++) // 枚举倍数
sum[i*k] += k*euler[i]; for(int i = ; i<MAXN; i++)
sum[i] += sum[i-];
} int main()
{
init();
int n;
while(scanf("%d", &n) &&n)
printf("%lld\n", sum[n]);
}
最新文章
- 使用Eclipse进行远程调试
- 开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀
- kubernetes听云实战发布版
- jquery删除动态增加的li
- redis五种数据类型的使用
- PAT (Advanced Level) 1028. List Sorting (25)
- js 学习之路8:for循环
- BZOJ2655: calc(dp 拉格朗日插值)
- springmvc.xml 中 <;url-pattern>;<;/url-pattern>;节点详解
- 从源码看Spring Boot 2.0.1
- GCC&;&;GDB在OI中的介绍
- Linux:软件包安装
- 对中文进行MD5加密的注意事项(Java版,编码问题)
- ubuntu 开机自启(2B的经历)
- MySQL:日期类型
- 在QTableView中某列中添加Button的导致滚动条滚动的时候消失的问题
- 开源轻量级分布式文件系统--FastDFS
- python数据分析之csv/txt数据的导入和保存
- NOIP 2002提高组 选数 dfs/暴力
- phpcms输出logo下拉实例