File size: 3,678 Bytes
1fd0050 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #include <bits/stdc++.h>
using namespace std;
void build_func(int cur, int rem, long long lo, long long hi, vector<vector<pair<int, int>>>& graph, const vector<int>& remain, int& node_cnt) {
if (lo > hi || rem == 0) return;
long long half = 1LL << (rem - 1);
// 0 side
long long lo0 = lo;
long long hi0 = min(hi, half - 1);
if (lo0 <= hi0) {
bool full0 = (lo0 == 0 && hi0 == half - 1);
int targ;
if (full0) {
targ = remain[rem - 1];
} else {
int nextn = ++node_cnt;
targ = nextn;
build_func(nextn, rem - 1, lo0, hi0, graph, remain, node_cnt);
}
graph[cur].emplace_back(targ, 0);
}
// 1 side
long long lo1 = max(lo, half);
long long hi1 = hi;
if (lo1 <= hi1) {
bool full1 = (lo1 == half && hi1 == ((1LL << rem) - 1));
int targ;
if (full1) {
targ = remain[rem - 1];
} else {
int nextn = ++node_cnt;
targ = nextn;
build_func(nextn, rem - 1, lo1 - half, hi1 - half, graph, remain, node_cnt);
}
graph[cur].emplace_back(targ, 1);
}
}
int main() {
long long L, R;
cin >> L >> R;
int D = (R == 0 ? 0 : 64 - __builtin_clzll(R));
int node_cnt = 2; // 1: start, 2: end
vector<int> remain(D + 1, 0);
remain[0] = 2;
for (int r = 1; r <= D; ++r) {
int newn = ++node_cnt;
remain[r] = newn;
}
vector<vector<pair<int, int>>> graph(node_cnt + 1);
for (int r = 1; r <= D; ++r) {
int from = remain[r];
int to = remain[r - 1];
graph[from].emplace_back(to, 0);
graph[from].emplace_back(to, 1);
}
for (int d = 1; d <= D; ++d) {
long long fl = (d == 1 ? 1LL : (1LL << (d - 1)));
long long fh = fl * 2 - 1;
long long al = max(L, fl);
long long ah = min(R, fh);
if (al > ah) continue;
bool is_full = (al == fl && ah == fh);
int remm = d - 1;
int targ = remain[remm];
if (is_full) {
graph[1].emplace_back(targ, 1);
} else {
if (d == 1) continue;
int subs = ++node_cnt;
graph[1].emplace_back(subs, 1);
long long olo = al - fl;
long long ohi = ah - fl;
build_func(subs, remm, olo, ohi, graph, remain, node_cnt);
}
}
// Now find reachable
vector<bool> used(node_cnt + 1, false);
queue<int> q;
q.push(1);
used[1] = true;
while (!q.empty()) {
int u = q.front();
q.pop();
for (auto& p : graph[u]) {
int v = p.first;
if (!used[v]) {
used[v] = true;
q.push(v);
}
}
}
vector<int> reachable;
for (int i = 1; i <= node_cnt; ++i) {
if (used[i]) reachable.push_back(i);
}
sort(reachable.begin(), reachable.end());
int newn = reachable.size();
map<int, int> remap;
for (int j = 0; j < newn; ++j) {
remap[reachable[j]] = j + 1;
}
vector<vector<pair<int, int>>> newgraph(newn + 1);
for (int oldi : reachable) {
int newi = remap[oldi];
for (auto& p : graph[oldi]) {
int olda = p.first;
int newa = remap[olda];
int vv = p.second;
newgraph[newi].emplace_back(newa, vv);
}
}
cout << newn << endl;
for (int i = 1; i <= newn; ++i) {
auto& e = newgraph[i];
int k = e.size();
cout << k;
for (auto& p : e) {
cout << " " << p.first << " " << p.second;
}
cout << endl;
}
return 0;
} |