You are on page 1of 12

Competitive Programming Special Interest Group

(CPSIG)
This document is written to help beginners in the world of competitive
programming. The aim of this document is to discuss some algorithms
and techniques which help in competitive coding. Some classic
problems on various Online Judges have been discussed. Also list of
some good questions have been compiled. There is no prerequisite as
such but knowledge of at least one programming language is still
preferred.

I hope this document helps you.

Amitayush Thakur, @CSA-BITS Pilani , Coding Team Member


amit9oct@gmail.com
https://www.facebook.com/amitayush.thakur

Introduction
Competitive Programming in summary, is this: Given wellknown Computer Science (CS) problems, solve them as quickly as
possible!.
Lets digest the terms one by one. The term well-known CS
problems implies that in competitive programming, we are dealing
with solved CS problems and not research problems (where the solutions
are still unknown). Definitely, some people (at least the problem setter)
have solved these problems before. 'Solve them' implies that we must
push our CS knowledge to a certain required level so that we can
produce working codes that can solve these problems too in terms of
getting the same output as the problem setter using the problem setters
secret input data. As quickly as possible is the competitive element
which is a very natural human behavior.
Please note that being well-versed in competitive programming is not
the end goal, it is just the means. The true end goal is to produce allrounded computer scientists/programmers who are much more ready to
produce better software or to face harder CS research problems in the
future.
The founders of ACM International Collegiate Programming Contest
(ICPC) have this vision.
Some general tips:
Type code fast: When you can solve the same number of
problems as your competitor, it is now down to typing speed.
Quickly Identify Problem Types: It is important to identify the
category of the problem. It is good know if it an adhoc or a DP or a
Graph problem. We will be discussing these in details.
Do Algorithm Analysis: It is important you must know how
efficient is your algorithm is and how much space it occupies.

Master Programming Languages: There are several


programming languages allowed in ICPC, including C/C++ and
Java. Which one should we master? Our experience gives us the
following answer: although we prefer C++ with built-in Standard
Template Library (STL), we can still use Java, although a bit
slower, but still has a powerful BigInteger, String Processing, and
GregorianCalendar API. Most of the competitive coder use C++ .
Although I personally prefer Java.
Master the Art of Testing Code: You thought you have nailed a
particular problem. You have identified its type, designed the
algorithm for it, calculated the algorithm's time/space complexity it will be within the time and memory limit given, and coded the
algorithm. But, your solution is still not Accepted (AC). The
reason is that you didn't test your algorithm on several test cases.
Practice and More Practice: The name says it all. Practice is
required for anything. You can start practicing from various online
judges including SPOJ, TOPCODER, CODECHEF , UVa Online
Judge etc.

Online Judges
An online judge is an online system to test programs in programming
contests. They are also used to practice for such contests. Many of these
systems organize their own contests. The system can compile and
execute codes, and test them with pre-constructed data.
The following are some popular online judges:
SPOJ:
1. It is a problems archive ,(Recommended For ALL
Beginners)
2. Start with problems having maximum number of
submissions. Solve first 20 problems then start skipping .
3. When you develop little confidence start following some
good coders (check their initial submissions) .
4. Then start solving problem topic wise.
5. Never get stuck for too long in initial period . Try to google
your doubts or contact someone ( BUT ONLY IN
BEGINNING ).
6. Before getting into live contests like codechef/codeforces
solve at least 50 problems on SPOJ.
CODECHEF:
1 Only 3 Contests per month(MUST for all).
2 Even if you are not able to solve a problem do always look at
its editorials and then code and submit it(because it is the
only way you will learn).
3 And even if you able to solve then also check the editorials
and look at codes of top coders . See how they implemented
their code.
CODEFORCES:
1. 4-5 2 Hrs long contest( Once you develop some confidence ).
TOPCODER:
1. Start once you have proper experience and can write code
very fast.

How does the judge work ?


You write codes and submit codes online . The judge runs your code and
checks the output of your program for several inputs and gives the result
based on your programs outputs. You must follow exact I/O(Input
Output) formats. Do not print statements like : please enter a number,
etc .
Each problem has constraints . Properly analyze the constraints.
Time Limit in seconds ( gives you an insight of what order of solution
it expects) -> time complexity analysis(discussed later).
The constraints on input ( very imp ): Most of the time you can
correctly guess the order of the solution by analyzing the input
constraints and time limit .
Memory Limit ( You need not bother unless you are using insanely
large amount of memory).
Types of errors you will encounter apart from wrong answer :
Run Time Error (Most Encountered):
SIGSEGV occurs when you are trying to access an invalid memory
location.(Generally when you give negative array indices). Dividing
by Zero / Taking modulo with zero.
SIGKILL is because of using too much memory.
NZEC occurs when your program doesn't terminate properly.
Compilation Error:
You need to learn the language syntax. Make sure that you are using
standard GNU compilers for C/C++ and jdk for Java.
Also you can compile your code from IDEONE.
Time Limit Exceeded(TLE):
Your program failed to generate all output within given time limit.
Always think of worst cases before you start coding .Always try to
avoid TLE.
Again do proper time complexity analysis of your solution .
Roughly 106 to 107 instructions pass in 1 second. But there is no
such hard and fast rule. It depends on the various other factors too.

Getting Started: Time Complexity


Without going into theoretical details time complexity of a program is
just the number of instruction the program will execute to perform a
particular task.
For example consider the following function fact() which is used to find
n! .
(The code is written in C++)

int fact(int n){


int prod=1;
for(int i=1;i<=n;i++){
prod*=i;
}
return prod;
}

If you carefully take a look at the code the first line ` int prod=1`
gets executed only once. The line ` prod*=i ` gets executed N times.
And the line ` return prod ` gets executed only once. Hence the
overall time complexity is hence 1*N + 2 . We ignore constants and just
say that the complexity of the program is O(n).

I will strongly recommend all of you to go through the following links to


know more about time complexity and order analysis.

Concept:
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=co
mplexity1
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=co
mplexity2
Video Tutorials:
http://www.youtube.com/watch?v=OpebHLAf99Y&list=PL2_aWCzG
MAwI9HK8YPVBjElbLbI3ufctn
http://www.youtube.com/watch?v=PFd5s0bHgAQ&list=PL2_aWCzGM
AwI9HK8YPVBjElbLbI3ufctn

Basic Mathematics and Adhoc Problems


GCD using Euclid's Algorithm:
Sieve of Erastothenes:
Concept and
Implementation: http://community.topcoder.com/tc?module=Static&d1=
tutorials&d2=math_for_topcoders
Uses: GCD - calculating GCD, LCM. Prime Sieve - Fast calculation of
prime numbers in a range.
GCD and Prime Sieve is the minimum you need to learn from this link.
Feel free to read the rest too if you have time.
Modular Exponentiation:
Concept: http://en.wikipedia.org/wiki/Modular_exponentiation
Implementation: http://machlearner.blogspot.in/2013/09/modularexponentiation.html
Uses: Calculating (a^n)%MOD in O(logn) time.
Matrix Exponentiation:
Concept: http://fusharblog.com/solving-linear-recurrence-forprogramming-contest/
Implementation: Refer to above link. It is essentially the same as
modular exponentiation for numbers, with matrix multiplication instead
of normal multiplication. It is highly recommended you implement this
on your own and not re-use code.
Uses: Solving Linear Recurrences like Fibonacci numbers in
O((d^3)*logn) time where d - dimension of the matrix.
Modular Inverse where MOD is a prime:
Concept: http://en.wikipedia.org/wiki/Modular_multiplicative_inverse
Implementation: http://machlearner.blogspot.in/2013/09/modularmultiplicative-inverse.html
Uses: To calculate nCr%MOD where MOD is prime. nCr =
(fact[n]/(fact[r]*fact[n-r]))%MOD = fact[n]%MOD *
mod_inv(fact[r]*fact[n-r], MOD)

Advanced Track(for those who have completed all above mentioned


concepts):
Primality Testing - Miller Rabbin:
Concept and
Implementation: http://community.topcoder.com/tc?module=Static&d1=
tutorials&d2=primalityTesting
Uses: To check whether a single number is prime or not.
Inclusion-Exclusion Principle:
Concept: http://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_
principle
Implementation:
Uses: To calculate probabilities / solve some counting problems where
the concept of inclusion-exclusion is involved.
Chinese Remainder Theorem:
Concept: http://en.wikipedia.org/wiki/Chinese_remainder_theorem
Implementation: http://machlearner.blogspot.in/2013/10/chineseremainder-theorem.html
Uses: Determine a number n that when divided by some given divisors
leaves given remainders
Euler Totient Function:
Concept: http://en.wikipedia.org/wiki/Euler%27s_totient_function
Implementation:
Uses: Too many to list. Please read the wiki page.
Advanced Counting Techniques - Polya Counting, Burnside's
Lemma:
Concept:
http://en.wikipedia.org/wiki/Burnside%27s_lemma
http://petr-mitrichev.blogspot.in/2008/11/burnsides-lemma.html

Problemset:
Basic Track:
SEQ, SPP, FIBOSUM, FIBTWIST, PRIME1, PRIMEZUK, DCEPCA06
, LASTDIG2, GCD2, KOPC12B,RANGZER2, ZSUM
Advanced Track:
PON, PAGAIN, HNUMBERS, POWPOW, NDIVPHI, SQFREE, ETF,
PROOT, NGM2

Would like to discuss the problem ZSUM. Before reading the problem
please go through the links suggested above and read about time
complexity.
Problem Statement:
For two given integers n and k find (Zn+Zn-1-2Zn-2)mod 10000007 ,
where Zn=Sn+Pn and Sn=1k+2k+3k+..+nk and Pn=11+22+33++nn.
Input
There are several test cases [ 10000 ].In each case two space separated
positive integers n and k are given.
For last test case n and k are given as 0 0 ,which is not to be processed.
1<n<200000000 , 0<k<1000000.
Output
For each case print the asked value in separate line.
Time Limit
1s
Strategies:
The easiest way to think will be finding Sn and Pn and then find Zn.
But if we carefully see the time taken to compute Sn alone is O(n log2k).
Cleary it will give TLE. ( As 200000000*log21000000 > 106)
So we need to change our approach what if I directly calculate (Zn+Zn-12Zn-2).
After some Maths one can easily arrive on the following formula.

(Zn+Zn-1-2Zn-2) = nn + nk + 2*(n-1)n-1 + 2*(n-1)k


Now the time complexity reduces to
O(log2(nk)) clearly log2(200000000*1000000)= 14 << 106
This should pass.
Here is the C implementation: (Do your own implementation before
seeing this)
#include<stdio.h>
#define MAX 10000007
int Modular_exp(int a,int n,int m)
{
long long x;
if(n==0)
return (1%m);
else if(n==1)
return (a%m);
else
{
if(n%2!=0)
{
x=Modular_exp(a,(n-1)/2,m);
return ((((a%m)*((x*x)%m))%m));
}
else
{
x=Modular_exp(a,n/2,m);
return ((((x*x)%m))%m);
}
}
}
int main()
{int n,k;
while(1)
{ scanf("%d %d",&n,&k);
if(n==0&&k==0)
break;
printf("%d\n",(Modular_exp(n,k,MAX)%MAX+2*Modular_exp(n1,k,MAX)%MAX+Modular_exp(n,n,MAX)%MAX+2*Modular_exp(n1,n-1,MAX)%MAX)%MAX);
}
return 0;
}

You might also like