https://vijos.org/p/1629
描述
八是个很有趣的数字啊。八=发,八八=爸爸,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。
来源
Rcx 原创
NOIP 2009·Dream Team 模拟赛 第一期 第一题
二进制生成子集
1 #include <algorithm> 2 #include <iostream> 3 4 using namespace std; 5 6 #define LL long long 7 LL n,a,b,ans,cant[23]; 8 9 LL GCD(LL a,LL b) 10 { 11 if(a%b==0) return b; 12 return GCD(b,a%b); 13 } 14 LL LCM(LL a,LL b) 15 { 16 return a/GCD(a,b)*b; 17 } 18 19 int main() 20 { 21 cin>>n; 22 for(int i=1;i<=n;i++) cin>>cant[i]; 23 cin>>a>>b; a--; 24 ans=b/8-a/8; //(1<<n)-1 所有情况数 25 for(int i=1;i<=(1<<n)-1;i++) 26 { 27 LL lcm=8,cnt=0; //保证最小公倍数 一定有8这个 因子 28 for(int j=0;j<n;j++) 29 if(i&(1<<j)) //压缩为2进制 从右开始 如果J==1 表示有第j个数 30 lcm=LCM(lcm,cant[j+1]),cnt++; 31 if(cnt&1) ans-=b/lcm-a/lcm; 32 else ans+=b/lcm-a/lcm; 33 } 34 cout<<ans; 35 return 0; 36 }