int query(int node, int treeStart, int treeEnd, int rangeStart, int rangeEnd) { Node temp = tree[node]; temp.lazy %= 3; if (temp.lazy > 0) { if (treeStart != treeEnd) { tree[2 * node].lazy += temp.lazy; tree[2 * node + 1].lazy += temp.lazy; } while (temp.lazy > 0) { int temp2 = temp.count[2]; temp.count[2] = temp.count[1]; temp.count[1] = temp.count[0]; temp.count[0] = temp2; temp.lazy--; } } if (treeStart > rangeEnd || treeEnd < rangeStart) return 0; if (treeStart >= rangeStart && treeEnd <= rangeEnd) return temp.count[0]; int mid, left, right; mid = treeStart + ((treeEnd - treeStart) >> 1); left = query(2 * node, treeStart, mid, rangeStart, rangeEnd); right = query(2 * node + 1, mid + 1, treeEnd, rangeStart, rangeEnd); return left + right; }
void update(int node, int treeStart, int treeEnd, int rangeStart, int rangeEnd) { Node temp = tree[node]; temp.lazy %= 3; if (temp.lazy > 0) { if (treeStart != treeEnd) { tree[2 * node].lazy += temp.lazy; tree[2 * node + 1].lazy += temp.lazy; } while (temp.lazy > 0) { int temp2 = temp.count[2]; temp.count[2] = temp.count[1]; temp.count[1] = temp.count[0]; temp.count[0] = temp2; temp.lazy--; } } if (treeStart > rangeEnd || treeEnd < rangeStart) return; if (treeStart >= rangeStart && treeEnd <= rangeEnd) { int temp2 = temp.count[2]; temp.count[2] = temp.count[1]; temp.count[1] = temp.count[0]; temp.count[0] = temp2; if (treeStart != treeEnd) { tree[2 * node].lazy++; tree[2 * node + 1].lazy++; } return; } int mid = treeStart + ((treeEnd - treeStart) >> 1); update(2 * node, treeStart, mid, rangeStart, rangeEnd); update(2 * node + 1, mid + 1, treeEnd, rangeStart, rangeEnd); temp.count[0] = tree[2 * node].count[0] + tree[2 * node + 1].count[0]; temp.count[1] = tree[2 * node].count[1] + tree[2 * node + 1].count[1]; temp.count[2] = tree[2 * node].count[2] + tree[2 * node + 1].count[2]; }