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 }
原文出处http://www.cnblogs.com/showson/