P1629八

P1629八
 
 

描述

八是个很有趣的数字啊。八=发,八八=爸爸,88=拜拜。当然最有趣的还是8用二进制表示是1000。怎么样,有趣吧。当然题目和这些都没有关系。

某个人很无聊,他想找出[a,b]中能被8整除却不能被其他一些数整除的数。

格式

输入格式

第一行一个数n,代表不能被整除的数的个数。

第二行n个数,中间用空格隔开。

第三行两个数a,b,中间一个空格。

输出格式

一个整数,为[a,b]间能被8整除却不能被那n个数整除的数的个数。

样例1

样例输入1[复制]

3
7764 6082 462
2166 53442

样例输出1[复制]

6378

限制

各个测试点1s

提示

对于30%的数据, 1≤n≤5,1≤a≤b≤100000。

对于100%的数据,1≤n≤15,1≤a≤b≤10^9,N个数全都小于等于10000大于等于1。

思路:容斥原理;

先将区间内是8的倍数的求出,然后在用容斥求不能被给的数整除的并且是8的倍数的数。

所以先将没个数与8求下最小公倍数,所以转换成求既能被8除又能被给的数除的数的个数,然后能被8除的总数减去就行。

复杂度(2n);

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<stdlib.h>
 5 #include<string.h>
 6 #include<math.h>
 7 #include<queue>
 8 using namespace std;
 9 typedef long long LL;
10 LL ans[100];
11 LL gcd(LL n,LL m);
12 int main(void)
13 {
14         int i,j,k;
15         LL n,m;
16         scanf("%d",&k);
17         for(i=0; i<k; i++)
18         {
19                 scanf("%lld",&ans[i]);
20         }
21         scanf("%lld %lld",&n,&m);
22         for(i=0; i<k; i++)
23         {
24                 ans[i]=ans[i]/gcd(ans[i],(LL)8)*8;
25         }
26         int cnt=m/8-(n-1)/8;
27         int sum=0;
28 
29         for(i=1; i<=(1<<k)-1; i++)
30         {
31                 int ak=0;
32                 int flag=0;  LL cn=1;
33                 for(j=0; j<k; j++)
34                 {
35                         if(i&(1<<j))
36                         {
37                                 ak++;
38                                 cn=cn/gcd(cn,ans[j])*ans[j];
39                                 if(cn>m)
40                                 {
41                                         flag=1;
42                                         break;
43                                 }
44                         }
45                 }
46                 if(!flag)
47                 {
48                         if(ak%2)
49                                 sum+=m/cn-((n-1)/cn);
50                         else sum-=m/cn-((n-1)/cn);
51                 }
52         }
53         printf("%d\n",cnt-sum);
54 }
55 LL gcd(LL n,LL m)
56 {
57         if(m==0)
58                 return n;
59         else if(n%m==0)
60                 return m;
61         else return gcd(m,n%m);
62 }

 

posted @ 2016-05-13 09:05  sCjTyC  阅读(245)  评论(0编辑  收藏  举报