UVA 10820 Send a Table 数论 欧拉函数
题目链接: https://vjudge.net/problem/UVA-10820
题目描述: 给你一个N, N <= 50000, 让你寻找N之内互素数的个数
解题思路: 欧拉函数, 由于位置颠倒是两个解, 在小于N的范围内只有(1, 1)x, y相等, 其他的都是不等的, 所以我们只需要算phi(2) + phi(3) + ...... phi(n), 然后 * 2 + 1即可
代码:
#include <iostream> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iterator> #include <cmath> #include <algorithm> #include <stack> #include <deque> #include <map> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,-0x3f,sizeof(a)) #define fi(n) for(i=0;i<n;i++) #define fj(m) for(j=0;j<m;j++) #define sca(x) scanf("%d",&x) #define scalld(x) scanf("%I64d",&x) #define print(x) printf("%d\n", x) #define printlld(x) printf("%I64d\n",x) #define de printf("=======\n") #define yes printf("YES\n") #define no printf("NO\n") typedef long long ll; using namespace std; const int maxn = 50000+100; int phi[maxn]; void phi_table( int n ) { for( int i = 2; i <= n; i++ ) { phi[i] = 0; } phi[1] = 1; for( int i = 2; i <= n; i++ ) { if( !phi[i] ) { for( int j = i; j <= n; j += i ) { if( !phi[j] ) phi[j] = j; phi[j] = phi[j] / i * (i-1); } } } } int main() { int n; mem0(phi); phi_table(50000); while( sca(n) == 1 && n ) { if( n == 1 ) { printf( "1\n" ); continue; } else { int res = 0; for( int i = 2; i <= n; i++ ) { res += phi[i]; } printf( "%d\n", 2 * res + 1 ); } } return 0; }
思考: 欧拉函数, 复杂度为O(nlognlogn), 本题就是直接打表然后计算和, 要注意这种思想, 倍数可以直接得到就转化成互素这种思想, 好好学数学
posted on 2017-08-22 17:07 FriskyPuppy 阅读(107) 评论(0) 编辑 收藏 举报