TOJ 4008 The Leaf Eaters(容斥定理)

Description

 As we all know caterpillars love to eat leaves. Usually, a caterpillar sits on leaf, eats as much of it as it can (or wants), then stretches out to its full length to reach a new leaf with its front end, and finally "hops" to it by contracting its back end to that leaf.

We have with us a very long, straight branch of a tree with leaves distributed uniformly along its length, and a set of caterpillars sitting on the first leaf. (Well, our leaves are big enough to accommodate upto 20 caterpillars!). As time progresses our caterpillars eat and hop repeatedly, thereby damaging many leaves. Not all caterpillars are of the same length, so different caterpillars may eat different sets of leaves. We would like to find out the number of leaves that will be undamaged at the end of this eating spree. We assume that adjacent leaves are a unit distance apart and the length of the caterpillars is also given in the same unit.

For example suppose our branch had 20 leaves (placed 1 unit apart) and 3 caterpillars of length 3, 2 and 5 units respectively. Then, first caterpillar would first eat leaf 1, then hop to leaf 4 and eat it and then hop to leaf 7 and eat it and so on. So the first caterpillar would end up eating the leaves at positions 1,4,7,10,13,16 and 19. The second caterpillar would eat the leaves at positions 1,3,5,7,9,11,13,15,17 and 19. The third caterpillar would eat the leaves at positions 1,6,11 and 16. Thus we would have undamaged leaves at positions 2,8,12,14,18 and 20. So the answer to this example is 6.

 

Input

The first line of the input contains two integers N and K, where N is the number of leaves and K is the number of caterpillars. Lines 2,3,...,K+1 describe the lengths of the K caterpillars. Line i+1 (1 ≤ i ≤ K) contains a single integer representing the length of the ith caterpillar.

You may assume that 1 ≤ N ≤ 1000000000 and 1 ≤ K≤ 20. The length of the caterpillars lie between 1 and N.

Output

A line containing a single integer, which is the number of leaves left on the branch after all the caterpillars have finished their eating spree.

 

Sample Input

20 3
3
2
5

Sample Output

6

Hint

You may use 64-bit integers (__int64 in C/C++) to avoid errors while multiplying large integers. The maximum value you can store in a 32-bit integer is 2^31-1, which is approximately 2 * 10^9. 64-bit integers can store values greater than 10^18.

Source

TOJ

 

这题的大概意思是:
有N个数,从1开始开始走每次走M个数,然后求没有走过的数的个数。
比如N=20,从1开始走每次走3步,即走到的数有1,4,7,10,13,16,19;
从1开始走每次走2步,即走到的数有1,3,5,7,9,11,13,15,17,19;
从1开始走每次走5步,即走到的数有1,6,11,16;
最后有2,8,12,14,18,20没有走到,一共有6个数,所以输出6。


这题可以转换成从1-20之间找出不被2,3,5整除的个数,根据容斥定理,解得此题!

【容斥定理】
|A∪B∪C|=|A|+|B|+|C|-|A∩B|-|A∩C|-|B∩C|+|A∩B∩C|

相交表示N个条件同时符合。

 

 1 #include <stdio.h>
 2 __int64 N,K,V[22];
 3 __int64 sum;
 4 
 5 __int64 gcd(__int64 a, __int64 b){
 6     if(a%b==0)return b;
 7     else return gcd(b,a%b);
 8 }
 9 __int64 lcm(__int64 a, __int64 b){
10     return a/gcd(a,b)*b;
11 }
12 
13 void dfs(int i, int flag, __int64 v){
14     if(i==K){
15         if(flag>0 && flag%2){
16             sum+=(N-1)/v;
17         }else if(flag>0 && !(flag%2)){
18             sum-=(N-1)/v;
19         }
20         return;
21     }
22     dfs(i+1,flag,v);
23     dfs(i+1,flag+1,lcm(V[i],v));
24 }
25 int main()
26 {   
27     while(scanf("%I64d %I64d",&N,&K)!=EOF){
28         for(int i=0; i<K; i++){
29             scanf("%I64d",&V[i]);
30         }
31         sum=1;
32         dfs(0,0,1);
33         printf("%I64d\n",N-sum);
34     }
35     return 0;
36 }

 

你可能感兴趣的:(400)