Overflow in intermediate arithmetic
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
Write an API that generates fancy sequences using the append, addAll, and multAll operations.
Implement the Fancy class:
Fancy() Initializes the object with an empty sequence.void append(val) Appends an integer val to the end of the sequence.void addAll(inc) Increments all existing values in the sequence by an integer inc.void multAll(m) Multiplies all existing values in the sequence by an integer m.int getIndex(idx) Gets the current value at index idx (0-indexed) of the sequence modulo 109 + 7. If the index is greater or equal than the length of the sequence, return -1.Example 1:
Input ["Fancy", "append", "addAll", "append", "multAll", "getIndex", "addAll", "append", "multAll", "getIndex", "getIndex", "getIndex"] [[], [2], [3], [7], [2], [0], [3], [10], [2], [0], [1], [2]] Output [null, null, null, null, null, 10, null, null, null, 26, 34, 20] Explanation Fancy fancy = new Fancy(); fancy.append(2); // fancy sequence: [2] fancy.addAll(3); // fancy sequence: [2+3] -> [5] fancy.append(7); // fancy sequence: [5, 7] fancy.multAll(2); // fancy sequence: [5*2, 7*2] -> [10, 14] fancy.getIndex(0); // return 10 fancy.addAll(3); // fancy sequence: [10+3, 14+3] -> [13, 17] fancy.append(10); // fancy sequence: [13, 17, 10] fancy.multAll(2); // fancy sequence: [13*2, 17*2, 10*2] -> [26, 34, 20] fancy.getIndex(0); // return 26 fancy.getIndex(1); // return 34 fancy.getIndex(2); // return 20
Constraints:
1 <= val, inc, m <= 1000 <= idx <= 105105 calls total will be made to append, addAll, multAll, and getIndex.Problem summary: Write an API that generates fancy sequences using the append, addAll, and multAll operations. Implement the Fancy class: Fancy() Initializes the object with an empty sequence. void append(val) Appends an integer val to the end of the sequence. void addAll(inc) Increments all existing values in the sequence by an integer inc. void multAll(m) Multiplies all existing values in the sequence by an integer m. int getIndex(idx) Gets the current value at index idx (0-indexed) of the sequence modulo 109 + 7. If the index is greater or equal than the length of the sequence, return -1.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Math · Design · Segment Tree
["Fancy","append","addAll","append","multAll","getIndex","addAll","append","multAll","getIndex","getIndex","getIndex"] [[],[2],[3],[7],[2],[0],[3],[10],[2],[0],[1],[2]]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1622: Fancy Sequence
class Node {
Node left;
Node right;
int l;
int r;
int mid;
long v;
long add;
long mul = 1;
public Node(int l, int r) {
this.l = l;
this.r = r;
this.mid = (l + r) >> 1;
}
}
class SegmentTree {
private Node root = new Node(1, (int) 1e5 + 1);
private static final int MOD = (int) 1e9 + 7;
public SegmentTree() {
}
public void modifyAdd(int l, int r, int inc) {
modifyAdd(l, r, inc, root);
}
public void modifyAdd(int l, int r, int inc, Node node) {
if (l > r) {
return;
}
if (node.l >= l && node.r <= r) {
node.v = (node.v + (node.r - node.l + 1) * inc) % MOD;
node.add = (node.add + inc) % MOD;
return;
}
pushdown(node);
if (l <= node.mid) {
modifyAdd(l, r, inc, node.left);
}
if (r > node.mid) {
modifyAdd(l, r, inc, node.right);
}
pushup(node);
}
public void modifyMul(int l, int r, int m) {
modifyMul(l, r, m, root);
}
public void modifyMul(int l, int r, int m, Node node) {
if (l > r) {
return;
}
if (node.l >= l && node.r <= r) {
node.v = (node.v * m) % MOD;
node.add = (node.add * m) % MOD;
node.mul = (node.mul * m) % MOD;
return;
}
pushdown(node);
if (l <= node.mid) {
modifyMul(l, r, m, node.left);
}
if (r > node.mid) {
modifyMul(l, r, m, node.right);
}
pushup(node);
}
public int query(int l, int r) {
return query(l, r, root);
}
public int query(int l, int r, Node node) {
if (l > r) {
return 0;
}
if (node.l >= l && node.r <= r) {
return (int) node.v;
}
pushdown(node);
int v = 0;
if (l <= node.mid) {
v = (v + query(l, r, node.left)) % MOD;
}
if (r > node.mid) {
v = (v + query(l, r, node.right)) % MOD;
}
return v;
}
public void pushup(Node node) {
node.v = (node.left.v + node.right.v) % MOD;
}
public void pushdown(Node node) {
if (node.left == null) {
node.left = new Node(node.l, node.mid);
}
if (node.right == null) {
node.right = new Node(node.mid + 1, node.r);
}
if (node.add != 0 || node.mul != 1) {
Node left = node.left, right = node.right;
left.v = (left.v * node.mul + (left.r - left.l + 1) * node.add) % MOD;
right.v = (right.v * node.mul + (right.r - right.l + 1) * node.add) % MOD;
left.add = (left.add * node.mul + node.add) % MOD;
right.add = (right.add * node.mul + node.add) % MOD;
left.mul = (left.mul * node.mul) % MOD;
right.mul = (right.mul * node.mul) % MOD;
node.add = 0;
node.mul = 1;
}
}
}
class Fancy {
private int n;
private SegmentTree tree = new SegmentTree();
public Fancy() {
}
public void append(int val) {
++n;
tree.modifyAdd(n, n, val);
}
public void addAll(int inc) {
tree.modifyAdd(1, n, inc);
}
public void multAll(int m) {
tree.modifyMul(1, n, m);
}
public int getIndex(int idx) {
return idx >= n ? -1 : tree.query(idx + 1, idx + 1);
}
}
/**
* Your Fancy object will be instantiated and called as such:
* Fancy obj = new Fancy();
* obj.append(val);
* obj.addAll(inc);
* obj.multAll(m);
* int param_4 = obj.getIndex(idx);
*/
// Accepted solution for LeetCode #1622: Fancy Sequence
// Auto-generated Go example from java.
func exampleSolution() {
}
// Reference (java):
// // Accepted solution for LeetCode #1622: Fancy Sequence
// class Node {
// Node left;
// Node right;
// int l;
// int r;
// int mid;
// long v;
// long add;
// long mul = 1;
//
// public Node(int l, int r) {
// this.l = l;
// this.r = r;
// this.mid = (l + r) >> 1;
// }
// }
//
// class SegmentTree {
// private Node root = new Node(1, (int) 1e5 + 1);
// private static final int MOD = (int) 1e9 + 7;
//
// public SegmentTree() {
// }
//
// public void modifyAdd(int l, int r, int inc) {
// modifyAdd(l, r, inc, root);
// }
//
// public void modifyAdd(int l, int r, int inc, Node node) {
// if (l > r) {
// return;
// }
// if (node.l >= l && node.r <= r) {
// node.v = (node.v + (node.r - node.l + 1) * inc) % MOD;
// node.add = (node.add + inc) % MOD;
// return;
// }
// pushdown(node);
// if (l <= node.mid) {
// modifyAdd(l, r, inc, node.left);
// }
// if (r > node.mid) {
// modifyAdd(l, r, inc, node.right);
// }
// pushup(node);
// }
//
// public void modifyMul(int l, int r, int m) {
// modifyMul(l, r, m, root);
// }
//
// public void modifyMul(int l, int r, int m, Node node) {
// if (l > r) {
// return;
// }
// if (node.l >= l && node.r <= r) {
// node.v = (node.v * m) % MOD;
// node.add = (node.add * m) % MOD;
// node.mul = (node.mul * m) % MOD;
// return;
// }
// pushdown(node);
// if (l <= node.mid) {
// modifyMul(l, r, m, node.left);
// }
// if (r > node.mid) {
// modifyMul(l, r, m, node.right);
// }
// pushup(node);
// }
//
// public int query(int l, int r) {
// return query(l, r, root);
// }
//
// public int query(int l, int r, Node node) {
// if (l > r) {
// return 0;
// }
// if (node.l >= l && node.r <= r) {
// return (int) node.v;
// }
// pushdown(node);
// int v = 0;
// if (l <= node.mid) {
// v = (v + query(l, r, node.left)) % MOD;
// }
// if (r > node.mid) {
// v = (v + query(l, r, node.right)) % MOD;
// }
// return v;
// }
//
// public void pushup(Node node) {
// node.v = (node.left.v + node.right.v) % MOD;
// }
//
// public void pushdown(Node node) {
// if (node.left == null) {
// node.left = new Node(node.l, node.mid);
// }
// if (node.right == null) {
// node.right = new Node(node.mid + 1, node.r);
// }
// if (node.add != 0 || node.mul != 1) {
// Node left = node.left, right = node.right;
// left.v = (left.v * node.mul + (left.r - left.l + 1) * node.add) % MOD;
// right.v = (right.v * node.mul + (right.r - right.l + 1) * node.add) % MOD;
// left.add = (left.add * node.mul + node.add) % MOD;
// right.add = (right.add * node.mul + node.add) % MOD;
// left.mul = (left.mul * node.mul) % MOD;
// right.mul = (right.mul * node.mul) % MOD;
// node.add = 0;
// node.mul = 1;
// }
// }
// }
//
// class Fancy {
// private int n;
// private SegmentTree tree = new SegmentTree();
//
// public Fancy() {
// }
//
// public void append(int val) {
// ++n;
// tree.modifyAdd(n, n, val);
// }
//
// public void addAll(int inc) {
// tree.modifyAdd(1, n, inc);
// }
//
// public void multAll(int m) {
// tree.modifyMul(1, n, m);
// }
//
// public int getIndex(int idx) {
// return idx >= n ? -1 : tree.query(idx + 1, idx + 1);
// }
// }
//
// /**
// * Your Fancy object will be instantiated and called as such:
// * Fancy obj = new Fancy();
// * obj.append(val);
// * obj.addAll(inc);
// * obj.multAll(m);
// * int param_4 = obj.getIndex(idx);
// */
# Accepted solution for LeetCode #1622: Fancy Sequence
MOD = int(1e9 + 7)
class Node:
def __init__(self, l, r):
self.left = None
self.right = None
self.l = l
self.r = r
self.mid = (l + r) >> 1
self.v = 0
self.add = 0
self.mul = 1
class SegmentTree:
def __init__(self):
self.root = Node(1, int(1e5 + 1))
def modifyAdd(self, l, r, inc, node=None):
if l > r:
return
if node is None:
node = self.root
if node.l >= l and node.r <= r:
node.v = (node.v + (node.r - node.l + 1) * inc) % MOD
node.add += inc
return
self.pushdown(node)
if l <= node.mid:
self.modifyAdd(l, r, inc, node.left)
if r > node.mid:
self.modifyAdd(l, r, inc, node.right)
self.pushup(node)
def modifyMul(self, l, r, m, node=None):
if l > r:
return
if node is None:
node = self.root
if node.l >= l and node.r <= r:
node.v = (node.v * m) % MOD
node.add = (node.add * m) % MOD
node.mul = (node.mul * m) % MOD
return
self.pushdown(node)
if l <= node.mid:
self.modifyMul(l, r, m, node.left)
if r > node.mid:
self.modifyMul(l, r, m, node.right)
self.pushup(node)
def query(self, l, r, node=None):
if l > r:
return 0
if node is None:
node = self.root
if node.l >= l and node.r <= r:
return node.v
self.pushdown(node)
v = 0
if l <= node.mid:
v = (v + self.query(l, r, node.left)) % MOD
if r > node.mid:
v = (v + self.query(l, r, node.right)) % MOD
return v
def pushup(self, node):
node.v = (node.left.v + node.right.v) % MOD
def pushdown(self, node):
if node.left is None:
node.left = Node(node.l, node.mid)
if node.right is None:
node.right = Node(node.mid + 1, node.r)
left, right = node.left, node.right
if node.add != 0 or node.mul != 1:
left.v = (left.v * node.mul + (left.r - left.l + 1) * node.add) % MOD
right.v = (right.v * node.mul + (right.r - right.l + 1) * node.add) % MOD
left.add = (left.add * node.mul + node.add) % MOD
right.add = (right.add * node.mul + node.add) % MOD
left.mul = (left.mul * node.mul) % MOD
right.mul = (right.mul * node.mul) % MOD
node.add = 0
node.mul = 1
class Fancy:
def __init__(self):
self.n = 0
self.tree = SegmentTree()
def append(self, val: int) -> None:
self.n += 1
self.tree.modifyAdd(self.n, self.n, val)
def addAll(self, inc: int) -> None:
self.tree.modifyAdd(1, self.n, inc)
def multAll(self, m: int) -> None:
self.tree.modifyMul(1, self.n, m)
def getIndex(self, idx: int) -> int:
return -1 if idx >= self.n else self.tree.query(idx + 1, idx + 1)
# Your Fancy object will be instantiated and called as such:
# obj = Fancy()
# obj.append(val)
# obj.addAll(inc)
# obj.multAll(m)
# param_4 = obj.getIndex(idx)
// Accepted solution for LeetCode #1622: Fancy Sequence
/**
* [1622] Fancy Sequence
*
* Write an API that generates fancy sequences using the append, addAll, and multAll operations.
* Implement the Fancy class:
*
* Fancy() Initializes the object with an empty sequence.
* void append(val) Appends an integer val to the end of the sequence.
* void addAll(inc) Increments all existing values in the sequence by an integer inc.
* void multAll(m) Multiplies all existing values in the sequence by an integer m.
* int getIndex(idx) Gets the current value at index idx (0-indexed) of the sequence modulo 10^9 + 7. If the index is greater or equal than the length of the sequence, return -1.
*
*
* Example 1:
*
* Input
* ["Fancy", "append", "addAll", "append", "multAll", "getIndex", "addAll", "append", "multAll", "getIndex", "getIndex", "getIndex"]
* [[], [2], [3], [7], [2], [0], [3], [10], [2], [0], [1], [2]]
* Output
* [null, null, null, null, null, 10, null, null, null, 26, 34, 20]
* Explanation
* Fancy fancy = new Fancy();
* fancy.append(2); // fancy sequence: [2]
* fancy.addAll(3); // fancy sequence: [2+3] -> [5]
* fancy.append(7); // fancy sequence: [5, 7]
* fancy.multAll(2); // fancy sequence: [5*2, 7*2] -> [10, 14]
* fancy.getIndex(0); // return 10
* fancy.addAll(3); // fancy sequence: [10+3, 14+3] -> [13, 17]
* fancy.append(10); // fancy sequence: [13, 17, 10]
* fancy.multAll(2); // fancy sequence: [13*2, 17*2, 10*2] -> [26, 34, 20]
* fancy.getIndex(0); // return 26
* fancy.getIndex(1); // return 34
* fancy.getIndex(2); // return 20
*
*
* Constraints:
*
* 1 <= val, inc, m <= 100
* 0 <= idx <= 10^5
* At most 10^5 calls total will be made to append, addAll, multAll, and getIndex.
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/fancy-sequence/
// discuss: https://leetcode.com/problems/fancy-sequence/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
// Credit: https://leetcode.com/problems/fancy-sequence/solutions/3182146/just-a-runnable-solution/
const MOD: i64 = 1_000_000_007;
struct Fancy {
seq: Vec<i64>,
increment: i64,
mult: i64,
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl Fancy {
fn new() -> Self {
Self {
seq: Vec::new(),
increment: 0,
mult: 1,
}
}
fn append(&mut self, val: i32) {
let v =
(((MOD + val as i64 - self.increment) % MOD) * self.mod_pow(self.mult, MOD - 2)) % MOD;
self.seq.push(v);
}
fn add_all(&mut self, inc: i32) {
self.increment = (self.increment + inc as i64) % MOD;
}
fn mult_all(&mut self, m: i32) {
let m = m as i64;
self.mult = (self.mult * m % MOD) % MOD;
self.increment = (self.increment * m % MOD) % MOD;
}
fn get_index(&self, idx: i32) -> i32 {
let idx = idx as usize;
if idx >= self.seq.len() {
-1
} else {
let v = ((self.seq[idx] * self.mult) % MOD + self.increment) % MOD;
v as _
}
}
fn mod_pow(&self, x: i64, y: i64) -> i64 {
let mut tot = 1;
let mut p = x;
let mut y = y;
while y > 0 {
if y & 1 == 1 {
tot = (tot * p) % MOD;
}
p = (p * p) % MOD;
y >>= 1;
}
tot
}
}
/**
* Your Fancy object will be instantiated and called as such:
* let obj = Fancy::new();
* obj.append(val);
* obj.add_all(inc);
* obj.mult_all(m);
* let ret_4: i32 = obj.get_index(idx);
*/
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_1622_example_1() {
let mut fancy = Fancy::new();
fancy.append(2); // fancy sequence: [2]
fancy.add_all(3); // fancy sequence: [2+3] -> [5]
fancy.append(7); // fancy sequence: [5, 7]
fancy.mult_all(2); // fancy sequence: [5*2, 7*2] -> [10, 14]
assert_eq!(fancy.get_index(0), 10); // return 10
fancy.add_all(3); // fancy sequence: [10+3, 14+3] -> [13, 17]
fancy.append(10); // fancy sequence: [13, 17, 10]
fancy.mult_all(2); // fancy sequence: [13*2, 17*2, 10*2] -> [26, 34, 20]
assert_eq!(fancy.get_index(0), 26); // return 26
assert_eq!(fancy.get_index(1), 34); // return 34
assert_eq!(fancy.get_index(2), 20); // return 20
}
}
// Accepted solution for LeetCode #1622: Fancy Sequence
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #1622: Fancy Sequence
// class Node {
// Node left;
// Node right;
// int l;
// int r;
// int mid;
// long v;
// long add;
// long mul = 1;
//
// public Node(int l, int r) {
// this.l = l;
// this.r = r;
// this.mid = (l + r) >> 1;
// }
// }
//
// class SegmentTree {
// private Node root = new Node(1, (int) 1e5 + 1);
// private static final int MOD = (int) 1e9 + 7;
//
// public SegmentTree() {
// }
//
// public void modifyAdd(int l, int r, int inc) {
// modifyAdd(l, r, inc, root);
// }
//
// public void modifyAdd(int l, int r, int inc, Node node) {
// if (l > r) {
// return;
// }
// if (node.l >= l && node.r <= r) {
// node.v = (node.v + (node.r - node.l + 1) * inc) % MOD;
// node.add = (node.add + inc) % MOD;
// return;
// }
// pushdown(node);
// if (l <= node.mid) {
// modifyAdd(l, r, inc, node.left);
// }
// if (r > node.mid) {
// modifyAdd(l, r, inc, node.right);
// }
// pushup(node);
// }
//
// public void modifyMul(int l, int r, int m) {
// modifyMul(l, r, m, root);
// }
//
// public void modifyMul(int l, int r, int m, Node node) {
// if (l > r) {
// return;
// }
// if (node.l >= l && node.r <= r) {
// node.v = (node.v * m) % MOD;
// node.add = (node.add * m) % MOD;
// node.mul = (node.mul * m) % MOD;
// return;
// }
// pushdown(node);
// if (l <= node.mid) {
// modifyMul(l, r, m, node.left);
// }
// if (r > node.mid) {
// modifyMul(l, r, m, node.right);
// }
// pushup(node);
// }
//
// public int query(int l, int r) {
// return query(l, r, root);
// }
//
// public int query(int l, int r, Node node) {
// if (l > r) {
// return 0;
// }
// if (node.l >= l && node.r <= r) {
// return (int) node.v;
// }
// pushdown(node);
// int v = 0;
// if (l <= node.mid) {
// v = (v + query(l, r, node.left)) % MOD;
// }
// if (r > node.mid) {
// v = (v + query(l, r, node.right)) % MOD;
// }
// return v;
// }
//
// public void pushup(Node node) {
// node.v = (node.left.v + node.right.v) % MOD;
// }
//
// public void pushdown(Node node) {
// if (node.left == null) {
// node.left = new Node(node.l, node.mid);
// }
// if (node.right == null) {
// node.right = new Node(node.mid + 1, node.r);
// }
// if (node.add != 0 || node.mul != 1) {
// Node left = node.left, right = node.right;
// left.v = (left.v * node.mul + (left.r - left.l + 1) * node.add) % MOD;
// right.v = (right.v * node.mul + (right.r - right.l + 1) * node.add) % MOD;
// left.add = (left.add * node.mul + node.add) % MOD;
// right.add = (right.add * node.mul + node.add) % MOD;
// left.mul = (left.mul * node.mul) % MOD;
// right.mul = (right.mul * node.mul) % MOD;
// node.add = 0;
// node.mul = 1;
// }
// }
// }
//
// class Fancy {
// private int n;
// private SegmentTree tree = new SegmentTree();
//
// public Fancy() {
// }
//
// public void append(int val) {
// ++n;
// tree.modifyAdd(n, n, val);
// }
//
// public void addAll(int inc) {
// tree.modifyAdd(1, n, inc);
// }
//
// public void multAll(int m) {
// tree.modifyMul(1, n, m);
// }
//
// public int getIndex(int idx) {
// return idx >= n ? -1 : tree.query(idx + 1, idx + 1);
// }
// }
//
// /**
// * Your Fancy object will be instantiated and called as such:
// * Fancy obj = new Fancy();
// * obj.append(val);
// * obj.addAll(inc);
// * obj.multAll(m);
// * int param_4 = obj.getIndex(idx);
// */
Use this to step through a reusable interview workflow for this problem.
Use a simple list or array for storage. Each operation (get, put, remove) requires a linear scan to find the target element — O(n) per operation. Space is O(n) to store the data. The linear search makes this impractical for frequent operations.
Design problems target O(1) amortized per operation by combining data structures (hash map + doubly-linked list for LRU, stack + min-tracking for MinStack). Space is always at least O(n) to store the data. The challenge is achieving constant-time operations through clever structure composition.
Review these before coding to avoid predictable interview regressions.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.