标签:
裸题。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <vector> 6 #include <algorithm> 7 8 using namespace std; 9 10 #define LL long long 11 #define eps 1e-8 12 #define lson l, m, rt<<1 13 #define rson m+1, r, rt<<1|1 14 #define mnx 2010 15 16 int fat[mnx]; 17 int main(){ 18 LL n; 19 while( scanf( "%I64d", &n ) != EOF && n ){ 20 int cnt = 0; 21 double m = n; 22 for( LL i = 2; i * i <= n; ++i ){ 23 if( n % i == 0 ){ 24 fat[cnt++] = i; 25 while( n % i == 0 ) 26 n /= i; 27 } 28 if( n == 1 ) break; 29 } 30 if( n != 1 ) fat[cnt++] = n; 31 for( int i = 0; i < cnt; ++i ) 32 m *= ( 1.0 - ( 1.0 / fat[i] ) ); 33 printf( "%I64d\n", (LL)(m+eps) ); 34 } 35 return 0; 36 }
题意:
就是给出一个奇素数,求出他的原根的个数。
定义:n的原根x满足条件0<x<n,并且有集合{ (xi mod n) | 1 <= i <=n-1 } 和集合{ 1, ..., n-1 }相等
定理:如果p有原根,则它恰有φ(φ(p))个不同的原根,p为素数,当然φ(p)=p-1,因此就有φ(p-1)个原根。。
具体看 这里
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <vector> 6 #include <algorithm> 7 8 using namespace std; 9 10 #define LL long long 11 #define eps 1e-8 12 #define lson l, m, rt<<1 13 #define rson m+1, r, rt<<1|1 14 #define mnx 2010 15 16 int fat[mnx]; 17 int main(){ 18 LL n; 19 while( scanf( "%I64d", &n ) != EOF && n ){ 20 int cnt = 0; 21 n--; 22 double m = n; 23 for( LL i = 2; i * i <= n; ++i ){ 24 if( n % i == 0 ){ 25 fat[cnt++] = i; 26 while( n % i == 0 ) 27 n /= i; 28 } 29 if( n == 1 ) break; 30 } 31 if( n != 1 ) fat[cnt++] = n; 32 for( int i = 0; i < cnt; ++i ) 33 m *= ( 1.0 - ( 1.0 / fat[i] ) ); 34 printf( "%I64d\n", (LL)(m+eps) ); 35 } 36 return 0; 37 }
欧拉函数求和。用了一个线性求欧拉函数的模板。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <vector> 6 #include <algorithm> 7 8 using namespace std; 9 10 #define LL long long 11 #define eps 1e-8 12 #define lson l, m, rt<<1 13 #define rson m+1, r, rt<<1|1 14 #define mnx 1000100 15 16 int pri[mnx], tot; 17 LL phi[mnx]; 18 bool isnot[mnx]; 19 void init(){ 20 phi[1] = 1; 21 for( int i = 2; i < mnx; ++i ){ 22 if( !isnot[i] ){ 23 phi[i] = i - 1; 24 pri[tot++] = i; 25 } 26 for( int j = 0; j < tot && i * pri[j] < mnx; ++j ){ 27 isnot[i*pri[j]] = 1; 28 if( i % pri[j] == 0 ){ 29 phi[i*pri[j]] = phi[i] * pri[j]; 30 break; 31 } 32 else phi[i*pri[j]] = phi[i] * ( pri[j] - 1 ); 33 } 34 } 35 } 36 int main(){ 37 init(); 38 for( int i = 3; i < mnx; ++i ){ 39 phi[i] += phi[i-1]; 40 } 41 int n; 42 while( scanf( "%d", &n ) != EOF && n ){ 43 printf( "%I64d\n", phi[n] ); 44 } 45 return 0; 46 }
POJ 3090 Visible Lattice Points
从( 0, 0 )看,问右上角在( n, n )的正方形内,能够看到多少个点。就是( x, y ), x与y互质的点都能看到。就是欧拉函数求和 sum, sum*2 + 3就是答案了( 0, 0 ), ( 1, 0 ), ( 0, 1 )三个点也要算上。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <vector> 6 #include <algorithm> 7 8 using namespace std; 9 10 #define LL long long 11 #define eps 1e-8 12 #define lson l, m, rt<<1 13 #define rson m+1, r, rt<<1|1 14 #define mnx 2010 15 16 LL euler( LL x ){ 17 double ret = x; 18 for( LL i = 2; i * i <= x; ++i ){ 19 if( x % i == 0 ) 20 ret *= ( i - 1.0 ) / i; 21 while( x % i == 0 ) 22 x /= i; 23 } 24 if( x > 1 ) ret *= ( x - 1.0 ) / x; 25 return (LL)( ret + eps ); 26 } 27 int main(){ 28 LL n; 29 int cas, kk = 1; 30 scanf( "%d", &cas ); 31 while( cas-- ){ 32 scanf( "%I64d", &n ); 33 printf( "%d %I64d ", kk++, n ); 34 LL ans = 0; 35 for( int i = 2; i <= n; ++i ) 36 ans += euler( (LL)i ); 37 printf( "%I64d\n", ans * 2 + 3 ); 38 } 39 return 0; 40 }
题意:给你一个数L,让你求出最小的一个数能被L整除,这个数满足每一位都是8,问这个数最少有多少位。
首先设这个有k位,则这个数可以表示为 8 / 9 * ( 10^k - 1 ) = L * m
-> 8 * ( 10^k - 1 ) = 9 * L * m;
设 d = gcd( 9L, 8 ) -> 8 / gcd( 9L, 8 ) * ( 10^k - 1 ) = 9 * L / gcd( 9L, 8 ) * m;
因为 8/gcd(9L,8) 与 9L/gcd(9L,8) 互质,则等式成立的话, (10^k-1) % ( 9L/gcd(9L,8) ) == 0;
gcd(9L, 8) = gcd(L, 8)。即 ( 10^k ) % ( 9L/gcd(L,8) ) == 1。。设 q = 9L/gcd(L,8)。。
由欧拉定理,当gcd(10,q) == 1,k = phi(q)是其中一个解。要求最小解,就要枚举phi(q)的所有因子,看是否满足 10^k % ( phi(q)的因子 ) == 1,取最小的那个。
若gcd( 10, q ) != 1,很明显方程无解。用了快速幂和二进制乘法( 因为有可能爆longlong)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <vector> 6 #include <algorithm> 7 8 using namespace std; 9 10 #define LL long long 11 #define eps 1e-8 12 #define lson l, m, rt<<1 13 #define rson m+1, r, rt<<1|1 14 #define mnx 100100 15 16 LL gcd( LL a, LL b ){ 17 return b == 0 ? a : gcd( b, a % b ); 18 } 19 LL phi( LL x ){ 20 double ret = x; 21 for( LL i = 2; i * i <= x; ++i ){ 22 if( x % i == 0 ) 23 ret *= ( i - 1.0 ) / i; 24 while( x % i == 0 ) 25 x /= i; 26 } 27 if( x > 1 ) ret *= ( x - 1.0 ) / x; 28 return (LL)( ret + eps ); 29 } 30 LL m, L; 31 LL mul( LL a, LL b ){ 32 LL ret = 0; 33 while( b ){ 34 if( b & 1 ) ret = ( ret + a ) % m; 35 a = ( a + a ) % m; 36 b >>= 1; 37 } 38 return ret; 39 } 40 int qpow( LL k ){ 41 LL ret = 1, x = 10; 42 while( k ){ 43 if( k & 1 ) ret = mul( ret, x ) % m; 44 x = mul( x, x ) % m; 45 k >>= 1; 46 } 47 return ret == 1 ? 1 : 0; 48 } 49 int main(){ 50 int kk = 1; 51 while( scanf( "%I64d", &L ) != EOF && L ){ 52 m = 9 * L / gcd( L, 8 ); 53 LL sum = phi( m ), ans = 1e15; 54 //cout << sum << endl; 55 if( gcd( 10, m ) != 1 ){ 56 printf( "Case %d: 0\n", kk++ ); continue; 57 } 58 for( LL i = 1; i * i <= sum; ++i ){ 59 if( sum % i == 0 ){ 60 if( qpow( i ) ) 61 ans = min( ans, i ); 62 if( qpow( sum / i) ) 63 ans = min( ans, sum/i ); 64 } 65 } 66 printf( "Case %d: %I64d\n", kk++, ans ); 67 } 68 return 0; 69 }
标签:
原文地址:http://www.cnblogs.com/LJ-blog/p/4352334.html