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张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。
比如当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)
(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 }