bzoj1853: [Scoi2010]幸运数字

容斥搞一搞。。

不能直接1<<n枚举所有状态,得回溯。。从大的开始决定选不选,然后最好把能被其他数整除的数除掉。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<string>
 7 
 8 using namespace std;
 9 
10 void setIO(const string& a) {
11     freopen((a+".in").c_str(), "r", stdin);
12     freopen((a+".out").c_str(), "w", stdout);
13 }
14 
15 typedef long long ll;
16 const int N = 10;
17 
18 const ll ten[11] = {1, (ll)1e1, (ll)1e2, (ll)1e3, (ll)1e4, (ll)1e5, (ll)1e6, (ll)1e7, (ll)1e8, (ll)1e9, (ll)1e10};
19 
20 ll seq[2 << N], a[1 << N], res;
21 int tot;
22 
23 void dfs_pre(int now, ll res) {
24     if(res) seq[tot++] = res;
25     if(now == N) return;
26     dfs_pre(now + 1, res * 10 + 6);
27     dfs_pre(now + 1, res * 10 + 8);
28 }
29 
30 ll ans = 0;
31 
32 ll gcd(ll a, ll b) {
33     return !b ? a : gcd(b, a % b);
34 }
35 
36 bool vis[1 << N];
37 
38 int n;
39 ll L, R;
40 
41 void dfs(int now, int cnt, ll lcm) {
42     if(now == -1) {
43         if(cnt & 1) ans += R / lcm - L / lcm;
44         else if(cnt > 0) ans -= R / lcm - L / lcm;
45         return;
46     }
47     dfs(now - 1, cnt, lcm);
48     ll g = gcd(lcm, a[now]);
49     if((double)lcm / g * a[now] <= R + 1) {
50         dfs(now - 1, cnt + 1, lcm / g * a[now] );
51     }
52 }
53 
54 int main() {
55     
56     dfs_pre(0, 0);
57     sort(seq, seq + tot);
58     for(int i = 0; i < tot; i++) {
59         int ok = 1;
60         for(int j = 0; j < i; j++) if(seq[i] % seq[j] == 0) ok = 0;
61         if(ok) a[n++] = seq[i];
62     }
63     
64 //    reverse(a, a + n);
65     cin >> L >> R; --L;
66     for(int i = n - 1; i >= 0; i--) {
67         if(a[i] <= R) {
68             dfs(i, 0, 1);
69             break;
70         }
71     }
72     cout << ans << endl;
73     
74     return 0;
75 }

 

posted @ 2015-11-30 10:38  Showson  阅读(229)  评论(0编辑  收藏  举报