首页 > 代码库 > [bzoj1853][Scoi2010][幸运数字] (容斥原理)
[bzoj1853][Scoi2010][幸运数字] (容斥原理)
Description
在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”。lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“近似幸运号码”。 现在lxhgww想知道在一段闭区间[a, b]内,“近似幸运号码”的个数。
Input
输入数据是一行,包括2个数字a和b
Output
输出数据是一行,包括1个数字,表示在闭区间[a, b]内“近似幸运号码”的个数
Sample Input
【样例输入1】
【样例输入2】
1 10
【样例输入2】
1234 4321
Sample Output
【样例输出1】
【样例输出2】
2
809
HINT
【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000
Solution
#include <stdio.h>#include <algorithm>#define N 10010#define L long longtemplate < class T > void EC(T &a , T &b){ T t=a; a=b; b=t;}template < class T > T GD(T a , T b){ return b ? GD(b , a % b) : a;}int _t,_n;bool V[N];L l , r , A[N] , ans;void PR(int x , L y){ if(y > r) return; if(x) A[++_t] = y; PR(x + 1 , y * 10 + 6); PR(x + 1 , y * 10 + 8);}void DF(int x , int y , L z){ if(x > _n) { if(y) ans += y & 1 ? r / z - (l - 1) / z : (l - 1) / z - r / z; return; } DF(x + 1 , y , z); L t = z / GD(z , A[x]); if(((double)A[x] * t) <= r) DF(x + 1 , y + 1 , A[x] * t);}int main(){ scanf("%lld%lld" , &l , &r); PR(0 , 0); std::sort(A + 1 , A + _t + 1); for(int i = 1;i <= _t;i++) if(!V[i]) { A[++_n]=A[i]; for(int j = i + 1;j <= _t;j++) if(A[j] % A[i] == 0) V[j]=1; } for(int i = 1;i + i <= _n;i++) EC(A[i],A[_n-i+1]); DF(1 , 0 , 1); printf("%lld\n",ans); return 0;}
[bzoj1853][Scoi2010][幸运数字] (容斥原理)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。