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 }
posted @ 2012-11-10 09:12  AC_Girl  阅读(158)  评论(0编辑  收藏  举报