poj 1091
题目:http://poj.org/problem?id=1091
按照我想的应该用高精度写的,写高精度求幂,和加减运算,但是题目数据不强,long long也过了,就懒得写高精度了,
题意是:找出 n + 1 个数( <= m ) 这(n + 1)个数最大公倍数是 1,首先求出 m 的所有质因子,然后用这些质因子构成 (n + 1)个数最大公倍数不是 1的情况,最后用总数减去这些情况
View Code
1 typedef long long ll; 2 const int N = 20001; 3 bool vis[N]; 4 int prime[N]; 5 int num,tnum; 6 ll tprime[N]; 7 ll ttp[N]; 8 int n,m; 9 ll kemp; 10 ll calmi(ll a,ll b) // 求幂(严格来说这样写是错误的,因为数据稍微一大就溢出了) 11 { 12 ll i; 13 ll temp = 1; 14 for(i = 0; i < b; i++) 15 temp *= a; 16 return temp; 17 } 18 19 void dfs(ll a,ll b,ll c) // 质因子组合 20 { 21 ll i; 22 if(b == c) 23 { 24 ll temp = m; 25 for(i = 0; i < c; i++) 26 { 27 temp /= ttp[i]; 28 } 29 kemp += calmi(temp,n); 30 } 31 else 32 { 33 for(i = a; i < tnum; i++) 34 { 35 ttp[b] = tprime[i]; 36 dfs(i + 1,b + 1,c); 37 } 38 } 39 } 40 void is_prime() // 打表求素数 41 { 42 int i,j; 43 for(i = 2; i <= N; i++) 44 { 45 if(!vis[i]) prime[num++] = i; 46 for(j = 2; j * i <= N; j++) 47 { 48 if(vis[i * j]) continue; 49 vis[i * j] = true; 50 } 51 } 52 } 53 void cal() // 分解质因子 54 { 55 ll i; 56 tnum = 0; 57 ll tt = m; 58 for(i = 0; i < num; i++) 59 { 60 if(tt == 1) break; 61 if(tt % prime[i] == 0) 62 { 63 tprime[tnum ++] = prime[i]; 64 while(tt % prime[i] == 0) tt /= prime[i]; 65 } 66 } 67 if(tt != 1) tprime[tnum ++] = tt; 68 ll temp = calmi(m,n); 69 for(i = 0; i < tnum; i++) 70 { 71 kemp = 0; 72 dfs(0,0,i + 1); 73 if(i % 2 == 0) // 容斥定理求 74 temp -= kemp; 75 else temp += kemp; 76 } 77 cout<<temp<<endl; 78 } 79 int main() 80 { 81 num = 0; 82 is_prime(); 83 while(cin>>n>>m) 84 { 85 cal(); 86 } 87 return 0; 88 }