poj 1091 跳騷

 1 /**
 2 題意: 求對於小於m的n個數, 求x1*a1 + x2*a2+x3*a3........+xn*an = 1
 3 即求 a1,a2,a3,。。。。an  的最大公約數爲1 , a1,a2....an 可重複
 4 原理 : 容斥原理 全部的 排序即 m^n ——不符合的狀況 ,即爲所求  5 不符合的狀況: 就是 這n個數有最大公約數 不是1, 即這n個數是m 的素因子的組合。。 
 6 一共有 m^n張卡片,若是減去其中含有公約數的卡片剩下的就是所求的結果
 7 舉個例子 n=2, m=360;    360=2^3*3^2*5   
 8 案 = (m ^ n) - (有公因數2的n元組)- (有公因數3的n元組)- (有公因數5的n元組)+ (有公因數2,3的n元組) +(有公因數2,5的n元組) + (有公因數3,5的n元組)- (有公因數2,3,5的n元組)。
 9 特殊之處:  m^n - (m/2)^n-(m/3)^n........+ (m/2*3)^n+ (m/2*5)^n......-(m/2*3*5)^n 10 -------> m^n(1-1/2^n)(1-1/3^n)(1-1/5^n)...... 11 好像是叫擴展歐拉函數 12 
13 **/
14 #include <iostream>
15 #include <algorithm>
16 #include <cstdio>
17 using namespace std;
18 
19 long long pow(long long a,long long b){
20     long long c =1;
21     while(b){
22         if(b&1)
23             c = c*a;
24         a =a*a;
25         b>>=1;
26     }
27     return c;
28 }
29 
30 long long res(long long n,long long m){
31     long long sm = pow(m,n);
32     long long ans = m;
33     long long temp ;
34     for(int i=2;i*i<=ans;i++)if(m%i==0){
35         temp = pow(i,n);
36         sm = sm/temp*(temp-1);
37         while(m%i==0) m /= i;
38     }
39     if(m>1){
40         temp = pow(m,n);
41         sm = sm/temp*(temp-1);
42     }
43     return sm;
44 
45 }
46 int main()
47 {
48     long long  n,m;
49     cin>>n>>m;
50     long long s = res(n,m);
51     cout<<s<<endl;
52     return 0;
53 }
相關文章
相關標籤/搜索