poj 1091 跳蚤

跳蚤
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 8482   Accepted: 2514

Description

Z城市居住着很多只跳蚤。在Z城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有N+1个自然数。其中最后一个是M,而前N个数都不超过M,卡片上允许有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数S,然后向左,或向右跳S个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。 
比如当N=2,M=18时,持有卡片(10, 15, 18)的跳蚤,就可以完成任务:他可以先向左跳10个单位长度,然后再连向左跳3次,每次15个单位长度,最后再向右连跳3次,每次18个单位长度。而持有卡片(12, 15, 18)的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。 
当确定N和M后,显然一共有M^N张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。 

Input

两个整数N和M(N <= 15 , M <= 100000000)。

Output

可以完成任务的卡片数。

Sample Input

2 4

Sample Output

12

Hint

这12张卡片分别是: 
(1, 1, 4), (1, 2, 4), (1, 3, 4), (1, 4, 4), (2, 1, 4), (2, 3, 4), 
(3, 1, 4), (3, 2, 4), (3, 3, 4), (3, 4, 4), (4, 1, 4), (4, 3, 4) 

Source

 
题意:略。
思路:每一种方案gcd()=1,如果这能得到,那么这道题就容易了。有点和一道 约瑟夫环变形类似。
题意有16种方案,还有4种方案,分别是,(2,2,4),(2,4,4),(4,2,4),(4,4,4);
他们的gcd()>1。
现在的问题就转化为求n+1个数字,(a1,a2,a3,,,an,M)=1的方案数。
n最多为15,M最大10^8。 我们从反面着手,求出()>1 的数量,用总数m^n减去即可。
m^n太大了,我们用java大数来做。
由于M的存在,求(a1,a2,a3,,,an,M)容易多了。
因为(a1,a2,,,an)=xi  如果xi不是M的因子的话,
那么最后(a1,a2,a3,,,an,M)=1 是为1的。这样的话这样筛选出M的素因子就可以了。容斥一下。
 
 
 1 import java.math.BigInteger;

 2 import java.util.Scanner;

 3 

 4 

 5 public class Main {

 6 

 7     static int yz[] = new int[1002];

 8     static int Q[] = new int[2002];

 9     static int len = 0;

10     static int qlen = 0;

11     public static void main(String[] args) {

12         Scanner cin = new Scanner(System.in);

13         while(cin.hasNext()){

14             int n = cin.nextInt();

15             int m = cin.nextInt();

16             BigInteger sum = BigInteger.valueOf(m);

17             sum = sum.pow(n);

18             /*

19              * 求m的素因子,并容斥

20              */

21             init(m);

22             BigInteger tmp = BigInteger.ZERO;

23             BigInteger sum2 = BigInteger.ZERO;

24             for(int i=1;i<=qlen;i++)

25             {

26                 if(Q[i]>0)

27                 {

28                     int k = m/Q[i];

29                     tmp=BigInteger.valueOf(k);

30                     tmp = tmp.pow(n);

31                     sum2=sum2.add(tmp);

32                 }

33                 else if(Q[i]<0)

34                 {

35                     Q[i] = -Q[i];

36                     int k = m/Q[i];

37                     tmp = BigInteger.valueOf(k);

38                     tmp = tmp.pow(n);

39                     tmp = tmp.multiply(BigInteger.valueOf(-1));

40                     sum2=sum2.add(tmp);

41                 }

42             }

43             sum2=sum2.multiply(BigInteger.valueOf(-1));

44             sum=sum.add(sum2);

45             System.out.println(sum);

46         }

47     }

48 

49     private static void init(int n) {

50         len = 0;

51         for(int i=2;i<=n/i;i++)

52         {

53             if(n%i==0)

54             {

55                 while(n%i==0)

56                     n=n/i;

57                 yz[++len] = i;

58             }

59         }

60         if(n!=1) yz[++len] = n;

61         qlen = 0;

62         Q[0]=-1;

63         for(int i=1;i<=len;i++)

64         {

65             int k = qlen;

66             for(int j=0;j<=k;j++)

67                 Q[++qlen]=-1*Q[j]*yz[i];

68         }

69     }

70 }

 

 

你可能感兴趣的:(poj)