/* ID: espr1t TASK: KEYWORDS: */ #include #include #include #include #include using namespace std; FILE *in; FILE *out; const int MAX = 100004; const int TREE = 262144; const long long INF = 1000000000000000001LL; struct Building { int parent, area, weight, strength; }; int n; Building a[MAX]; vector v[MAX]; long long area[MAX], tree[TREE]; int firstIndex[MAX], lastIndex[MAX], nextIndex = 0; void update(int idx, long long val) { idx += (TREE >> 1); while (idx > 0) { tree[idx] += val; idx >>= 1; } } long long query(int idx1, int idx2) { if (idx1 > idx2) return 0; idx1 += (TREE >> 1), idx2 += (TREE >> 1); if (idx1 == idx2) return tree[idx1]; long long ret = 0; ret += tree[idx1]; bool flag1 = !(idx1 & 1); idx1 >>= 1; ret += tree[idx2]; bool flag2 = (idx2 & 1); idx2 >>= 1; while (idx1 != idx2) { if (flag1) ret += tree[(idx1 << 1) | 1]; flag1 = !(idx1 & 1); idx1 >>= 1; if (flag2) ret += tree[(idx2 << 1) | 0]; flag2 = (idx2 & 1); idx2 >>= 1; } return ret; } void buildTree(int node) { firstIndex[node] = nextIndex++; for (int i = 0; i < (int)v[node].size(); i++) { buildTree(v[node][i]); } lastIndex[node] = nextIndex - 1; } bool simulate(int turns) { area[0] = INF; for (int i = 1; i <= n; i++) area[i] = a[i].area; memset(tree, 0, sizeof(tree)); for (int i = 1; i <= turns; i++) { area[a[i].parent] -= a[i].area; if (area[a[i].parent] < 0) return false; update(firstIndex[i], a[i].weight); } for (int i = 1; i <= n; i++) { int idx1 = firstIndex[i] + 1, idx2 = lastIndex[i]; if (query(idx1, idx2) > a[i].strength) return false; } return true; } void solve() { for (int i = 1; i <= n; i++) v[a[i].parent].push_back(i); buildTree(0); int ans = n + 1; int left = 1, right = n; while (left <= right) { int mid = (left + right) / 2; if (simulate(mid)) left = mid + 1; else right = mid - 1, ans = mid; } if (ans > n) { fprintf(out, "OK\n"); return; } area[0] = INF; for (int i = 1; i <= n; i++) area[i] = a[i].area; for (int i = 1; i <= ans; i++) { area[a[i].parent] -= a[i].area; } if (area[a[ans].parent] < 0) { fprintf(out, "IMPOSSIBLE %d\n", ans); } else { fprintf(out, "COLLAPSE %d\n", ans); } } int main(void) { in = stdin; out = stdout; in = fopen("building.in", "rt"); out = fopen("building.out", "wt"); fscanf(in, "%d", &n); for (int i = 1; i <= n; i++) fscanf(in, "%d %d %d %d", &a[i].parent, &a[i].area, &a[i].weight, &a[i].strength); solve(); return 0; }