Uva 11426 - GCD - Extreme (II) 欧拉函数
2016-03-25 21:52
369 查看
链接:戳这里
Given the value of N, you will have to find the value of G. The definition of G is given below:
i<N j≤N
G = ∑ ∑ GCD(i, j)
i=1 j=i+1
Here GCD(i, j) means the greatest common divisor of integer i and integer j.
For those who have trouble understanding summation notation, the meaning of G is given in the
following code:
G=0;
for(i=1;i<N;i++)
for(j=i+1;j<=N;j++)
{
G+=gcd(i,j);
}
/*Here gcd() is a function that finds the greatest common divisor of the two input numbers*/
Input
The input file contains at most 100 lines of inputs. Each line contains an integer N (1 < N < 4000001).
The meaning of N is given in the problem statement. Input is terminated by a line containing a single
zero.
Output
For each line of input produce one line of output. This line contains the value of G for the corresponding
N. The value of G will fit in a 64-bit signed integer.
Sample Input
10
100
200000
0
Sample Output
67
13015
143295493160
题意:输入正整数n,求gcd(1,2)+gcd(1,3)+gcd(2,3)+...+gcd(n-1,n),即对所有的满足(1<=i<j<=n)的数对(i,j)所对应的gcd(i,j)之和。比如当n==4时 ans=gcd(1,2)+gcd(1,3)+gcd(2,3)+gcd(1,4)+gcd(2,4)+gcd(3,4)
先设 f
=gcd(1,n)+gcd(2,n)+...+gcd(n-1,n)
那么 ans=f[2]+f[3]+...+f
递推一下sum
=sum[n-1]+f
所以现在只需要求f
,我们先设g(x,n)=i 表示gcd(x,n)==i的有多少个 显然x肯定是n的约数
其实出现gcd马上就要想到欧拉函数了 gcd(x,n)==i -> gcd(x/i,n/i)==1 也就是找出phi[n/i]的个数了
但是直接暴力找每次的f
的话,肯定是会超时的,所以模拟打表的过程处理f
这里也是技巧啊 涨姿势
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 4000000
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
/*
令f
={ gcd(1,n)+gcd(2,n)+gcd(3,n)+...+gcd(n-1,n) }
s
=f[2]+f[3]+f[4]....f
s
表示答案
-> s
=s[n-1]+f
;
*/
ll f[4000100],phi[4000100],sum[4000100];
void init(){
mst(phi,0);
phi[1]=1;
for(int i=2;i<=MAX;i++){
if(phi[i]) continue;
for(int j=i;j<=MAX;j+=i){
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
mst(f,0);
for(int i=1;i<=MAX;i++){
for(int j=i*2;j<=MAX;j+=i){
f[j]+=(ll)phi[j/i]*i;
}
}
sum[2]=f[2];
for(int i=3;i<=MAX;i++) sum[i]=sum[i-1]+f[i];
}
int main(){
init();
int n;
while(scanf("%d",&n)!=EOF){
if(n==0) break;
printf("%lld\n",sum
);
}
return 0;
}
Given the value of N, you will have to find the value of G. The definition of G is given below:
i<N j≤N
G = ∑ ∑ GCD(i, j)
i=1 j=i+1
Here GCD(i, j) means the greatest common divisor of integer i and integer j.
For those who have trouble understanding summation notation, the meaning of G is given in the
following code:
G=0;
for(i=1;i<N;i++)
for(j=i+1;j<=N;j++)
{
G+=gcd(i,j);
}
/*Here gcd() is a function that finds the greatest common divisor of the two input numbers*/
Input
The input file contains at most 100 lines of inputs. Each line contains an integer N (1 < N < 4000001).
The meaning of N is given in the problem statement. Input is terminated by a line containing a single
zero.
Output
For each line of input produce one line of output. This line contains the value of G for the corresponding
N. The value of G will fit in a 64-bit signed integer.
Sample Input
10
100
200000
0
Sample Output
67
13015
143295493160
题意:输入正整数n,求gcd(1,2)+gcd(1,3)+gcd(2,3)+...+gcd(n-1,n),即对所有的满足(1<=i<j<=n)的数对(i,j)所对应的gcd(i,j)之和。比如当n==4时 ans=gcd(1,2)+gcd(1,3)+gcd(2,3)+gcd(1,4)+gcd(2,4)+gcd(3,4)
先设 f
=gcd(1,n)+gcd(2,n)+...+gcd(n-1,n)
那么 ans=f[2]+f[3]+...+f
递推一下sum
=sum[n-1]+f
所以现在只需要求f
,我们先设g(x,n)=i 表示gcd(x,n)==i的有多少个 显然x肯定是n的约数
其实出现gcd马上就要想到欧拉函数了 gcd(x,n)==i -> gcd(x/i,n/i)==1 也就是找出phi[n/i]的个数了
但是直接暴力找每次的f
的话,肯定是会超时的,所以模拟打表的过程处理f
这里也是技巧啊 涨姿势
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 4000000
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
/*
令f
={ gcd(1,n)+gcd(2,n)+gcd(3,n)+...+gcd(n-1,n) }
s
=f[2]+f[3]+f[4]....f
s
表示答案
-> s
=s[n-1]+f
;
*/
ll f[4000100],phi[4000100],sum[4000100];
void init(){
mst(phi,0);
phi[1]=1;
for(int i=2;i<=MAX;i++){
if(phi[i]) continue;
for(int j=i;j<=MAX;j+=i){
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
mst(f,0);
for(int i=1;i<=MAX;i++){
for(int j=i*2;j<=MAX;j+=i){
f[j]+=(ll)phi[j/i]*i;
}
}
sum[2]=f[2];
for(int i=3;i<=MAX;i++) sum[i]=sum[i-1]+f[i];
}
int main(){
init();
int n;
while(scanf("%d",&n)!=EOF){
if(n==0) break;
printf("%lld\n",sum
);
}
return 0;
}
相关文章推荐
- 1006 电梯时间问题 ACID 00733616
- c++实验2--计算出标准体重,输出体重状态
- 三、 list类型、set类型和zset类型
- 经典算法 总结
- HDU 1262 寻找素数对
- leetcode 123. Best Time to Buy and Sell Stock III
- 关于Sqlite数据库连接Android
- Linux 套接字编程中的 5 个隐患
- 招商银行远程开发终端体验简谈
- 面试笔试试题精选
- 关于__attribute__((packed))
- 2016春招腾讯笔试题
- UVA 10635——Prince and Princess
- Android代码生成器设计文档
- D16
- Leetcode 122. Best Time to Buy and Sell Stock II
- 逆向工程实战分享
- Mac Os X server企业配置管理pad产品,控制PAD权限
- c++传递数组给函数
- TCP连接状态详解 http://blog.csdn.net/mei922/article/details/4801858