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 }

 

 
posted @ 2014-10-31 14:56  芷水  阅读(271)  评论(0编辑  收藏  举报