BZOJ 2705: [SDOI2012]Longge的问题(euler函数)
2015-10-05 09:59
246 查看
2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1638 Solved: 1030
[Submit][Status][Discuss]
Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。Input
一个整数,为N。Output
一个整数,为所求的答案。Sample Input
6Sample Output
15HINT
【数据范围】对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
题目中要求出∑gcd(i,N)(1<=i<=N)。
枚举n的约数k,令s(k)为满足gcd(m,n)=k,(1<=m<=n)m的个数,则ans=sigma(k*s(k)) (k为n的约数)
因为gcd(m,n)=k,所以gcd(m/k,n/k)=1,于是s(k)=euler(n/k)
phi可以在根号的时间内求出
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define LL long long
using namespace std;
const int MAXN = 1000000 + 10;
int read()
{
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f *= -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
return x * f;
}
int euler(int n)
{
int m = (int) sqrt(n + 0.5);
int ans = n;
for(int i=2;i<=m;i++) if(n % i == 0)
{
ans = ans / i * (i - 1);
while(n % i == 0) n /= i;
}
if(n > 1) ans = ans / n * (n - 1);
return ans;
}
int main()
{
int n; n = read();
long long ans = 0;
for(int i=1;i*i<=n;i++)
{
if(n % i == 0)
{
ans += i * euler(n / i);
if(n / i != i)
ans += (n / i) * euler(i);
}
}
printf("%lld\n", ans);
return 0;
}
相关文章推荐
- Android Studio的top level element is not completed问题
- http_banner获取v0.2
- 数据库以及线程发生死锁的原理及必要条件,如何避免死锁
- 四则运算
- 删除数据库关键数据文件后实例是否会崩溃
- Bootstrap CSS——表单(一)
- 在C#中动态地添加控件
- LaTeX分情况公式的书写
- 浅尝硬盘分区表
- Laravel 启动流程
- HTML5学习之二:HTML5中的表单2
- Storm系列(十一)架构分析之Supervisor-管理Worker进程的事件线程
- 使用 Python3 抓取网页的简单范例
- HDU 5050 Divided Land (二进制上的最大公约数)
- ubuntu(linux)下截图
- 【Linux 移植 】——3、移植 u-boot-2012.04.01 之 修改代码(时钟,SDRAM,UART)
- linux screen
- Win10预览版10558:新增“寻找我的设备”防盗功能
- UVALive 6258 Non-boring sequences 分治
- LCA o(nlogn)