memo [ 何桁目まで作ったか ] [ 使った 1 の数 ] [ idealとの違い ] [ mod 3 ] [ mod 7 ] [ smaller or not ]
#include <algorithm> #include <complex> #include <iostream> #include <map> #include <numeric> #include <queue> #include <set> #include <sstream> #include <stack> #include <vector> #include <cassert> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #define REP(i, n) for(int i=0; i<(int)n; ++i) #define FOR(i, c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i) #define ALL(c) (c).begin(),(c).end() #define each(i, c) FOR(i, c) #define VAR(a) cout << #a << " : " << a << endl; #define LOG() cout << __LINE__ << ", " << __func__ << endl; typedef long long int lli; using namespace std; const int D = 32; pair<lli, lli> memo[D][D][D][3][7][2]; vector<int> ideal; vector<int> v; int maxone; int K; pair<lli, lli> rec(int digit, int one, int diff, int mod3, int mod7, bool small) { pair<lli, lli> &ret = memo[digit][one][diff][mod3][mod7][small]; if (ret.first != -1) return ret; if (maxone < one) return ret = make_pair(0, 0); if (K < diff) return ret = make_pair(0, 0); if (digit == v.size()) { return (one && mod3 == 0 && mod7 != 0) ? make_pair(0, 1) : make_pair(0, 0); } lli sum = 0; lli cnt = 0; pair<lli, lli> p; // sum, cnt if (small) { // add 1 p = rec(digit + 1, one + 1, diff + (ideal[digit] == 0), (mod3 * 2 + 1) % 3, (mod7 * 2 + 1) % 7, true); cnt += p.second; sum += p.second * (1 << (v.size() - digit - 1)); sum += p.first; // add 0 p = rec(digit + 1, one, diff + (ideal[digit] == 1), (mod3 * 2) % 3, (mod7 * 2) % 7, true); cnt += p.second; sum += p.first; } else { // add 1 if (v[digit] == 1) { p = rec(digit + 1, one + 1, diff + (ideal[digit] == 0), (mod3 * 2 + 1) % 3, (mod7 * 2 + 1) % 7, false); cnt += p.second; sum += p.second * (1 << (v.size() - digit - 1)); sum += p.first; } // add 0 p = rec(digit + 1, one, diff + (ideal[digit] == 1), (mod3 * 2) % 3, (mod7 * 2) % 7, v[digit] == 1); cnt += p.second; sum += p.first; } return ret = make_pair(sum, cnt); } void f(vector<int> &v, int n) { v.clear(); while (n) { v.push_back(n % 2); n /= 2; } while (v.size() < D - 1) v.push_back(0); reverse(v.begin(), v.end()); return ; } lli g(lli n) { fill(&memo[0][0][0][0][0][0], &memo[D - 1][D - 1][D - 1][3 - 1][7 - 1][2], make_pair(-1, -1)); f(v, n); return rec(0, 0, 0, 0, 0, false).first; } int main(int argc, char *argv[]) { int tc; cin >> tc; while (tc--) { int start, end, i; cin >> start >> end >> maxone >> i >> K; f(ideal, i); static int tc = 0; cout << "Case " << ++tc << ": " << g(end) - g(start - 1) << endl; } return 0; }