| #include <iostream> |
| #include <vector> |
| #include <map> |
| #include <tuple> |
| #include <algorithm> |
|
|
| using namespace std; |
|
|
| |
| struct Edge { |
| int to; |
| int weight; |
| }; |
|
|
| |
| |
| int N_nodes = 2; |
| vector<Edge> adj[105]; |
| |
| |
| map<tuple<int, long long, long long>, int> memo; |
|
|
| |
| |
| |
| int get_node(int k, long long low, long long high) { |
| |
| if (low > high) return 0; |
| |
| |
| long long max_val = (1LL << k) - 1; |
| low = max(0LL, low); |
| high = min(max_val, high); |
| |
| if (low > high) return 0; |
| |
| |
| |
| if (k == 0) return 2; |
| |
| |
| auto key = make_tuple(k, low, high); |
| if (memo.count(key)) return memo[key]; |
| |
| long long M = 1LL << (k - 1); |
| |
| |
| |
| |
| long long l0 = low; |
| long long h0 = min(high, M - 1); |
| |
| |
| |
| |
| long long l1 = max(low, M) - M; |
| long long h1 = high - M; |
| |
| |
| int u0 = 0, u1 = 0; |
| if (l0 <= h0) u0 = get_node(k - 1, l0, h0); |
| if (l1 <= h1) u1 = get_node(k - 1, l1, h1); |
| |
| |
| if (u0 == 0 && u1 == 0) return 0; |
| |
| |
| int id = ++N_nodes; |
| if (u0 != 0) adj[id].push_back({u0, 0}); |
| if (u1 != 0) adj[id].push_back({u1, 1}); |
| |
| |
| return memo[key] = id; |
| } |
|
|
| int main() { |
| |
| ios_base::sync_with_stdio(false); |
| cin.tie(NULL); |
|
|
| long long L, R; |
| if (!(cin >> L >> R)) return 0; |
| |
| |
| auto get_len = [&](long long x) { |
| if (x == 0) return 0; |
| return 64 - __builtin_clzll(x); |
| }; |
| |
| int lenL = get_len(L); |
| int lenR = get_len(R); |
| |
| |
| |
| |
| for (int len = lenL; len <= lenR; ++len) { |
| |
| long long start_range = (len == lenL) ? L : (1LL << (len - 1)); |
| long long end_range = (len == lenR) ? R : (1LL << len) - 1; |
| |
| if (start_range > end_range) continue; |
| |
| |
| |
| |
| long long suffix_start = start_range - (1LL << (len - 1)); |
| long long suffix_end = end_range - (1LL << (len - 1)); |
| |
| int child = get_node(len - 1, suffix_start, suffix_end); |
| if (child != 0) { |
| adj[1].push_back({child, 1}); |
| } |
| } |
| |
| |
| cout << N_nodes << "\n"; |
| for (int i = 1; i <= N_nodes; ++i) { |
| cout << adj[i].size(); |
| for (auto& e : adj[i]) { |
| cout << " " << e.to << " " << e.weight; |
| } |
| cout << "\n"; |
| } |
| |
| return 0; |
| } |