| #include <iostream> |
| #include <vector> |
| #include <map> |
| #include <tuple> |
| #include <algorithm> |
|
|
| using namespace std; |
|
|
| |
| struct Edge { |
| int weight; |
| int to; |
| }; |
|
|
| |
| |
| |
| int node_count = 2; |
| map<tuple<int, long long, long long>, int> memo; |
| vector<Edge> adj[105]; |
|
|
| |
| |
| int get_node(int k, long long l, long long r) { |
| |
| if (k == 0) return 2; |
| |
| |
| auto state = make_tuple(k, l, r); |
| if (memo.count(state)) return memo[state]; |
| |
| |
| int id = ++node_count; |
| memo[state] = id; |
| |
| long long mid = 1LL << (k - 1); |
| |
| |
| |
| |
| |
| if (l < mid) { |
| long long next_r = min(r, mid - 1); |
| |
| int target = get_node(k - 1, l, next_r); |
| adj[id].push_back({0, target}); |
| } |
| |
| |
| if (r >= mid) { |
| long long next_l = max(l, mid) - mid; |
| long long next_r = r - mid; |
| |
| int target = get_node(k - 1, next_l, next_r); |
| adj[id].push_back({1, target}); |
| } |
| |
| return id; |
| } |
|
|
| int main() { |
| |
| ios_base::sync_with_stdio(false); |
| cin.tie(NULL); |
|
|
| int L_in, R_in; |
| if (!(cin >> L_in >> R_in)) return 0; |
|
|
| |
| |
| for (int len = 1; len <= 20; ++len) { |
| long long lower = 1LL << (len - 1); |
| long long upper = (1LL << len) - 1; |
| |
| long long curL = max((long long)L_in, lower); |
| long long curR = min((long long)R_in, upper); |
| |
| if (curL > curR) continue; |
| |
| |
| |
| |
| |
| int target = get_node(len - 1, curL - lower, curR - lower); |
| |
| adj[1].push_back({1, target}); |
| } |
| |
| |
| cout << node_count << "\n"; |
| for (int i = 1; i <= node_count; ++i) { |
| cout << adj[i].size(); |
| for (const auto &e : adj[i]) { |
| cout << " " << e.to << " " << e.weight; |
| } |
| cout << "\n"; |
| } |
| |
| return 0; |
| } |