2
/** Segment tree class to store sum of a range and maximum available seats in a row */4
long sum[]; // store sum of seats in a range5
long segTree[]; // store maximum seats in a range8
public SegTree(int n, int m) {11
segTree = new long[4 * n];12
sum = new long[4 * n];13
build(0, 0, n - 1, m);16
private void build(int index, int lo, int hi, long val) {18
segTree[index] = val; // initialize segement tree with initial seat capacity19
sum[index] = val; // initialize "sum" with initial seat capacity of a row22
int mid = (lo + hi) / 2;23
build(2 * index + 1, lo, mid, val); // build left sub tree24
build(2 * index + 2, mid + 1, hi, val); // build right sub tree27
segTree[2 * index + 1],28
segTree[2 * index + 2]); // maximum seats in a row for subtrees29
sum[index] = sum[2 * index + 1] + sum[2 * index + 2]; // sum of seats in a range32
private void update(int index, int lo, int hi, int pos, int val) {33
/** Method to update segment tree based on the available seats in a row */39
int mid = (lo + hi) / 2;40
if (pos <= mid) { // position to update is in left41
update(2 * index + 1, lo, mid, pos, val);42
} else { // position to update is in right43
update(2 * index + 2, mid + 1, hi, pos, val);45
// update segment tree and "sum" based on the update in "pos" index46
segTree[index] = Math.max(segTree[2 * index + 1], segTree[2 * index + 2]);47
sum[index] = sum[2 * index + 1] + sum[2 * index + 2];50
public void update(int pos, int val) {51
update(0, 0, n - 1, pos, val);54
public int gatherQuery(int k, int maxRow) {55
return gatherQuery(0, 0, n - 1, k, maxRow);58
private int gatherQuery(int index, int lo, int hi, int k, int maxRow) {59
/** Method to check if seats are available in a single row */60
if (segTree[index] < k || lo > maxRow) return -1;61
if (lo == hi) return lo;62
int mid = (lo + hi) / 2;63
int c = gatherQuery(2 * index + 1, lo, mid, k, maxRow);65
c = gatherQuery(2 * index + 2, mid + 1, hi, k, maxRow);70
public long sumQuery(int k, int maxRow) {71
return sumQuery(0, 0, n - 1, k, maxRow);74
private long sumQuery(int index, int lo, int hi, int l, int r) {75
if (lo > r || hi < l) return 0; // not in range76
if (lo >= l && hi <= r) return sum[index]; // in range77
int mid = (lo + hi) / 2;78
return sumQuery(2 * index + 1, lo, mid, l, r) + sumQuery(2 * index + 2, mid + 1, hi, l, r);83
int[] rowSeats; // stores avaiable seats in a row, helps to find the vacant seat in a row85
public BookMyShow(int n, int m) {86
segTree = new SegTree(n, m);87
rowSeats = new int[n];88
Arrays.fill(rowSeats, m); // initialize vacant seats count to "m" for all the rows91
public int[] gather(int k, int maxRow) {92
int row = segTree.gatherQuery(k, maxRow); // find row which has k seats93
if (row == -1) return new int[] {}; // can't find a row with k seats94
int col = segTree.m - rowSeats[row]; // find column in the row which has k seats95
rowSeats[row] -= k; // reduce the seats96
segTree.update(row, rowSeats[row]); // update the segment tree97
return new int[] {row, col};100
public boolean scatter(int k, int maxRow) {101
long sum = segTree.sumQuery(0, maxRow); // find the sum for the given range [0, maxRow]102
if (sum < k) return false; // can't find k seats in [0, maxRow]104
for (int i = 0; i <= maxRow && k != 0; i++) {105
if (rowSeats[i] > 0) { // if current row has seats then allocate those seats106
long t = Math.min(rowSeats[i], k);109
segTree.update(i, rowSeats[i]); // update the segment tree