本来是想出来了的,,,,但是有个地方写挫了一直没发现,sad
就是dfs的时候我传的pos传错了QAQ
这题用容斥很好想
首先在区间[l, r]能被a整除的数有r/a-(l-1)/a,下取整。
而这题要求的是
其中B是区间内能被8整除的数,Ai分别为能整除所给的数的集合
那么我们用容斥加加减减即可。
同时要注意,算整除a和b的数并不是算a×b的数,而是lcm(a, b)
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue> using namespace std; #define rep(i, n) for(int i=0; i<(n); ++i) #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) #define CC(i,a) memset(i,a,sizeof(i)) #define read(a) a=getint() #define print(a) printf("%d", a) #define dbg(x) cout << (#x) << " = " << (x) << endl #define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; } #define printarr1(a, b) for1(_, 1, b) cout << a[_] << ‘\t‘; cout << endl inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<‘0‘||c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘&&c<=‘9‘; c=getchar()) r=r*10+c-‘0‘; return k*r; } inline const int max(const int &a, const int &b) { return a>b?a:b; } inline const int min(const int &a, const int &b) { return a<b?a:b; } typedef unsigned long long ll; ll l, r, ans, a[18]; int n; ll get(ll c) { return r/c-(l-1)/c; } ll gcd(ll a, ll b) { return b?gcd(b, a%b):a; } void dfs(int x, ll c, int pos) { if(c>r) return; if(x&1) ans-=get(c); else ans+=get(c); for1(i, pos+1, n) dfs(x+1, c/gcd(c, a[i])*a[i], i); } int main() { read(n); for1(i, 1, n) read(a[i]); read(l); read(r); dfs(0, 8, 0); printf("%lld\n", ans); return 0; }
描述
八是个很有趣的数字啊。八=发,八八=爸爸,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 模拟赛 第一期 第一题
时间: 2024-11-04 12:22:43