Competitive programming has two halves: designing an algorithm that is correct and fast enough, and implementing it without bugs, quickly. This quick-revision chapter sets up the implementation side for Java: a template you’ll reuse for every problem, the number pitfalls that silently produce wrong answers, and the small amount of maths the book assumes.
Competitive programming ke do hisse hain: aisa algorithm design karna jo sahi bhi ho aur fast bhi, aur use bina bugs ke, jaldi implement karna. Yeh quick-revision chapter Java ke liye implementation wala hissa set karta hai: ek template jo har problem mein kaam aayega, number wale traps jo chupchaap galat answer de dete hain, aur woh thodi si maths jo book maan ke chalti hai.
1.1Programming languages
The book’s examples are C++. Everything on this site is translated to Java, which is a perfectly good contest language:
- The JIT compiler makes it fast — usually within a small factor of C++ for the same algorithm.
- The library has what you need —
ArrayList,TreeMap,PriorityQueue,BigInteger, sorting and binary search. - There’s no undefined behaviour — out-of-bounds reads throw an exception instead of silently returning garbage.
Its weak spots are predictable, and this chapter fixes most of them: slow default I/O, the cost of boxing (List<Integer> stores objects, not ints), and a small default recursion depth.
Start every solution from this template. solve is the only part you change.
Book ke examples C++ mein hain. Is site pe sab kuch Java mein translate kiya gaya hai — aur Java contest ke liye bilkul theek language hai:
- JIT compiler ise fast banata hai — same algorithm C++ se zyada slow nahi hota.
- Library mein zaroorat ki har cheez hai —
ArrayList,TreeMap,PriorityQueue,BigInteger, sorting aur binary search. - Koi undefined behaviour nahi — array ke bahar padhoge toh exception aayega, chupchaap garbage value nahi.
Kamzoriyan pehle se pata hain, aur yeh chapter unme se zyaadatar theek kar deta hai: default I/O slow hai, boxing ka kharcha (List<Integer> objects rakhta hai, ints nahi), aur default recursion depth chhoti hai.
Har solution isi template se shuru karo. Badalna sirf solve hai.
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.util.StringTokenizer; public class Template { public static void main(String[] args) throws IOException { FastReader in = new FastReader(System.in); PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))); solve(in, out); out.flush(); // nothing reaches the screen until you flush } static void solve(FastReader in, PrintWriter out) throws IOException { int n = in.nextInt(); long sum = 0; for (int i = 0; i < n; i++) sum += in.nextLong(); out.println(sum); } /** Whitespace-separated tokens, read line by line: many times faster than Scanner. */ static class FastReader { private final BufferedReader br; private StringTokenizer st; FastReader(InputStream stream) { br = new BufferedReader(new InputStreamReader(stream), 1 << 16); } /** The next token, or null at the end of the input. */ String next() throws IOException { while (st == null || !st.hasMoreTokens()) { String line = br.readLine(); if (line == null) return null; st = new StringTokenizer(line); } return st.nextToken(); } int nextInt() throws IOException { return Integer.parseInt(next()); } long nextLong() throws IOException { return Long.parseLong(next()); } double nextDouble() throws IOException { return Double.parseDouble(next()); } /** The rest of the current line is dropped; this returns the next whole line (spaces kept). */ String nextLine() throws IOException { st = null; return br.readLine(); } }}My notesMere notes
1.2Input and output
Input is usually numbers and strings separated by spaces and newlines, and the tokens are read the same way whichever separator is used. Scanner is convenient but slow: it parses with regular expressions, which can take seconds on 10⁶ numbers. The template’s FastReader reads whole lines through a BufferedReader and splits them with a StringTokenizer.
The same applies to output. System.out.println in a loop can flush every line. Collect output in a PrintWriter and flush() once at the end; if you forget the flush, nothing is printed at all.
Input aam taur pe numbers aur strings hote hain jo spaces aur newlines se alag hote hain — separator koi bhi ho, tokens ek hi tarah padhe jaate hain. Scanner aasaan hai par slow: regular expressions se parse karta hai, aur 10⁶ numbers pe seconds laga sakta hai. Template ka FastReader BufferedReader se poori line padhta hai aur StringTokenizer se todta hai.
Output ka bhi yahi haal hai: loop mein System.out.println har line pe flush kar sakta hai. Output PrintWriter mein jama karo aur end mein ek baar flush() karo — flush bhool gaye toh kuch print hi nahi hoga!
/** Whitespace-separated tokens, read line by line: many times faster than Scanner. */static class FastReader { private final BufferedReader br; private StringTokenizer st; FastReader(InputStream stream) { br = new BufferedReader(new InputStreamReader(stream), 1 << 16); } /** The next token, or null at the end of the input. */ String next() throws IOException { while (st == null || !st.hasMoreTokens()) { String line = br.readLine(); if (line == null) return null; st = new StringTokenizer(line); } return st.nextToken(); } int nextInt() throws IOException { return Integer.parseInt(next()); } long nextLong() throws IOException { return Long.parseLong(next()); } double nextDouble() throws IOException { return Double.parseDouble(next()); } /** The rest of the current line is dropped; this returns the next whole line (spaces kept). */ String nextLine() throws IOException { st = null; return br.readLine(); }}My notesMere notes
1.3Working with numbers
Integers and overflow
int holds about ±2.1·10⁹ and long about ±9.2·10¹⁸. The classic bug is in the book too: even when the variable is long, a * a with int operands is computed in int, overflows, and only then gets widened. Java doesn’t warn you or throw an exception; it silently gives the same wrong number the book shows.
int mein lagbhag ±2.1·10⁹ aata hai aur long mein ±9.2·10¹⁸. Book wala classic bug: variable long ho tab bhi, int operands ka a * a pehle int mein calculate hota hai, overflow hota hai, aur phir long banta hai. Java na warning deta hai na exception — chupchaap wahi galat number deta hai jo book dikhati hai.
static long[] overflowDemo() { int a = 123456789; long wrong = a * a; // int * int is computed in int, THEN widened: -1757895751 long right = (long) a * a; // widen first: 15241578750190521 return new long[] {wrong, right};}int r = a * b; | -1,757,895,751 | Overflow! The true result wrapped around modulo 2³², silently. |
long r = a * b; // a, b are int | -1,757,895,751 | Same wrong value: the int result overflows first, then gets widened to long. |
long r = (long) a * b; | 15,241,578,750,190,521 | Correct: widen BEFORE the operation. |
BigInteger (exact) | 15,241,578,750,190,521 | The true value. |
Remainders of negative numbers
x % m | -1 | Java keeps the sign of x, so this can be negative. |
Math.floorMod(x, m) | 2 | Always in 0..m−1: what “x mod m” means in maths. |
/** Throws ArithmeticException instead of silently wrapping around. Great for debugging. */static long safeMultiply(long a, long b) { return Math.multiplyExact(a, b);}/** When even long is not enough (|x| > 9·10^18), BigInteger has no limit. */static BigInteger twoToThe(int n) { return BigInteger.ONE.shiftLeft(n);}Modular arithmetic
When an answer is huge, problems ask for it modulo a number, usually 10⁹ + 7. You can take the remainder after every +, − and ×, so the numbers stay small:
Jab answer bahut bada ho, problem use kisi number ke modulo maangti hai — aksar 10⁹ + 7. Har +, − aur × ke baad remainder le sakte ho, toh numbers chhote hi rehte hain:
static final int MOD = 1_000_000_007; /** n! mod m, taking the remainder after every multiplication so nothing overflows. */static long factorialMod(int n, long m) { long x = 1; for (int i = 2; i <= n; i++) { x = x * i % m; } return x % m;} /** Java's % keeps the sign of the left operand: -7 % 3 == -1. floorMod gives 0..m-1. */static long mod(long x, long m) { return Math.floorMod(x, m);}Floating point
Some decimals can’t be stored exactly: 0.3 * 3 + 0.1 is 0.9999999999999999, not 1.0. Never compare doubles with ==. Instead, treat them as equal when they differ by less than ε (e.g. 10⁻⁹). double represents integers exactly only up to 2⁵³.
When printing, String.format("%.9f", x) uses your computer’s locale. In some locales, such as German, that prints 0,333333333 with a comma, which a judge marks wrong. Pass Locale.US.
Kuch decimals exactly store nahi hote: 0.3 * 3 + 0.1 ka answer 0.9999999999999999 hai, 1.0 nahi. Doubles ko kabhi == se compare mat karo — jab difference ε (jaise 10⁻⁹) se kam ho, tab barabar maano. double integers ko sirf 2⁵³ tak exactly rakhta hai.
Print karte waqt String.format("%.9f", x) tumhare computer ka locale use karta hai — kuch locales (jaise German) mein 0,333333333 comma ke saath print hota hai, aur judge use galat maanta hai. Locale.US pass karo.
static boolean nearlyEqual(double a, double b) { return Math.abs(a - b) < 1e-9;} /** Always format with Locale.US: in some locales "%.9f" prints a comma, e.g. 0,333333333. */static String format(double x) { return String.format(Locale.US, "%.9f", x);}My notesMere notes
1.4Shortening code
C++ contestants shorten code with typedef and #define macros. Java has neither, and that avoids the book’s own macro bug: #define SQ(a) a*a turns SQ(3+3) into 3+3*3+3 = 15. In Java you shorten code safely with:
- small static helper methods (
static long sq(long a) { return a * a; }). They are type-checked and evaluate their argument once. varfor long generic types:var adj = new ArrayList<List<Integer>>();- static imports:
import static java.lang.Math.*;lets you writemax(a, b). - one reusable template, so the boilerplate is written once.
Keep code readable: a contest program is short, but you still have to debug it under pressure.
C++ wale typedef aur #define macros se code chhota karte hain. Java mein dono nahi hain — aur isse book wala macro bug bhi bach jaata hai: #define SQ(a) a*a mein SQ(3+3) ban jaata hai 3+3*3+3 = 15. Java mein code safely chhota karne ke tareeke:
- chhote static helper methods (
static long sq(long a) { return a * a; }) — type-checked hain, aur argument ek hi baar evaluate hota hai. varlambe generic types ke liye:var adj = new ArrayList<List<Integer>>();- static imports:
import static java.lang.Math.*;likho, phir seedhamax(a, b). - ek reusable template, taaki boilerplate ek hi baar likhna pade.
Code readable rakho — contest program chhota hota hai, par pressure mein debug bhi tumhe hi karna hai.
My notesMere notes
1.5Mathematics
Sums and progressions
These closed forms come up constantly:
Yeh closed forms baar-baar kaam aate hain:
- Arithmetic progression (constant difference): for n terms. Example: 3 + 7 + 11 + 15 = 4·18/2 = 36.
- Geometric progression (constant ratio k): . Example: 3 + 6 + 12 + 24 = (48 − 3)/1 = 45, and in particular 1 + 2 + 4 + … + 2ⁿ⁻¹ = 2ⁿ − 1.
- Harmonic sum: 1 + 1/2 + … + 1/n ≤ log₂ n + 1. This bound shows up later in complexity analysis.
- Arithmetic progression (difference constant): n terms ke liye . Jaise 3 + 7 + 11 + 15 = 4·18/2 = 36.
- Geometric progression (ratio k constant): . Jaise 3 + 6 + 12 + 24 = (48 − 3)/1 = 45, aur khaas taur pe 1 + 2 + 4 + … + 2ⁿ⁻¹ = 2ⁿ − 1.
- Harmonic sum: 1 + 1/2 + … + 1/n ≤ log₂ n + 1 — yeh bound aage complexity analysis mein dikhega.
/** 1 + 2 + ... + n */static long sumTo(long n) { return n * (n + 1) / 2;} /** 1² + 2² + ... + n² */static long sumSquares(long n) { return n * (n + 1) * (2 * n + 1) / 6;}/** a + ... + b with `count` terms and a constant difference. */static long arithmetic(long a, long b, long count) { return count * (a + b) / 2;} /** a + ak + ak² + ... + b with ratio k > 1. */static long geometric(long a, long b, long k) { return (b * k - a) / (k - 1);}Sets, logic and functions
- Sets: a set S has 2^|S| subsets. Intersection (∩), union (∪), complement and difference (A \ B) are the operations you’ll use, including later as bitmasks in chapter 10.
- Logic: ¬ (not), ∧ (and), ∨ (or), ⇒ (implies), ⇔ (equivalent). ∀ means “for all” and ∃ means “there exists”.
- Floor and ceiling: ⌊x⌋ rounds down and ⌈x⌉ rounds up. Careful: Java’s integer
/truncates toward zero, so-7 / 2is-3while ⌊−7/2⌋ = −4. UseMath.floorDiv. For positive numbers, ⌈a/b⌉ is(a + b - 1) / b, with no floating point needed. - Factorial n! = 1·2·…·n, and Fibonacci f(0)=0, f(1)=1, f(n)=f(n−1)+f(n−2). f(90) still fits in a
long; f(93) does not.
- Sets: set S ke 2^|S| subsets hote hain. Intersection (∩), union (∪), complement aur difference (A \ B) — yahi operations use honge, chapter 10 mein bitmasks ki tarah bhi.
- Logic: ¬ (not), ∧ (and), ∨ (or), ⇒ (implies), ⇔ (equivalent). ∀ = “sabke liye”, ∃ = “koi to hai”.
- Floor aur ceiling: ⌊x⌋ neeche round, ⌈x⌉ upar round. Dhyaan do: Java ka integer
/zero ki taraf truncate karta hai —-7 / 2=-3, jabki ⌊−7/2⌋ = −4.Math.floorDivuse karo. Positive numbers ke liye ⌈a/b⌉ =(a + b - 1) / b— floating point ki zaroorat hi nahi. - Factorial n! = 1·2·…·n, aur Fibonacci f(0)=0, f(1)=1, f(n)=f(n−1)+f(n−2). f(90) abhi bhi
longmein fit hai; f(93) nahi.
/** Integer division in Java truncates toward zero: -7 / 2 == -3, but ⌊-7/2⌋ = -4. */static long floorDiv(long a, long b) { return Math.floorDiv(a, b);} /** ⌈a/b⌉ for a ≥ 0 and b > 0, without floating point. */static long ceilDiv(long a, long b) { return (a + b - 1) / b;}Logarithms
log_k(x) = a exactly when kᵃ = x. Intuitively, it’s how many times you can divide x by k before reaching 1: log₂ 32 = 5 because 32 → 16 → 8 → 4 → 2 → 1. That’s why algorithms that halve something each step run in O(log n). Two facts are handy: log(ab) = log a + log b, and x has ⌊log_b x⌋ + 1 digits in base b. For example, 123 = 1111011₂ has 7 bits.
log_k(x) = a tabhi jab kᵃ = x. Seedhi samajh: x ko k se kitni baar divide karoge 1 tak pahunchne ke liye — log₂ 32 = 5, kyunki 32 → 16 → 8 → 4 → 2 → 1. Isi wajah se jo algorithm har step pe kuch aadha karta hai, woh O(log n) mein chalta hai. Do kaam ki baatein: log(ab) = log a + log b, aur base b mein x ke ⌊log_b x⌋ + 1 digits hote hain — jaise 123 = 1111011₂ mein 7 bits.
/** ⌊log2 x⌋ for x > 0, exactly (no floating point). */static int log2(long x) { return 63 - Long.numberOfLeadingZeros(x);} /** Number of digits of x in base b: ⌊log_b(x)⌋ + 1. */static int digits(long x, int base) { int d = 0; do { d++; x /= base; } while (x > 0); return d;}My notesMere notes
1.6Contests and resources
- IOI is the olympiad for school students, and ICPC is the team contest for university students. ICPC’s Asia regionals include several sites in India, and topics there need more maths than at the IOI.
- Online contests: Codeforces (rated rounds most weeks), AtCoder, CodeChef and LeetCode’s weekly contests. Google’s Code Jam and Kick Start, mentioned in the book, were shut down in 2023.
- Practice: this site links every chapter to the CSES Problem Set (cses.fi), written by the book’s author. Solving its problems in order is a proven path.
- Books: Introduction to Algorithms (CLRS), Algorithm Design (Kleinberg–Tardos), The Algorithm Design Manual (Skiena), and Competitive Programming (Halim).
- IOI school students ka olympiad hai, aur ICPC university students ka team contest. ICPC ke Asia regionals ke kai sites India mein hote hain, aur wahan IOI se zyada maths chahiye.
- Online contests: Codeforces (lagbhag har hafte rated rounds), AtCoder, CodeChef aur LeetCode ke weekly contests. Book mein jinka zikr hai, Google ke Code Jam aur Kick Start, woh 2023 mein band ho gaye.
- Practice: is site ka har chapter CSES Problem Set (cses.fi) se juda hai — ise book ke author ne hi banaya hai. Iske problems order mein solve karna ek tested raasta hai.
- Books: Introduction to Algorithms (CLRS), Algorithm Design (Kleinberg–Tardos), The Algorithm Design Manual (Skiena), aur Competitive Programming (Halim).