Uva 10288 – Coupons

Category : DP, PIE, Probability
Solution:
First I will discuss DP solution.
Let f(x) = # of expected move to achieve x different coupons.
We know already f(0), f(1)…. ,f(x-1);
Now To achieve x different moves, Lets consider a coupon. We have two case

    The coupons is one of the x-1 of f(x-1)
    This could be different from the x-1 of f(x-1)

This lead us to a dp solution .
f(x) = \dfrac{x-1}{n} \{1 + f(x) \} + \dfrac{n-x+1}{n} \{1 + f(x-1) \}
This leads us to a closed form
f(x) = \dfrac{n}{n-x+1} + f(x-1)

code :

//
//  main.cpp
//  10288 - Coupons
//
//  Created by Repon Macbook on 12/28/15.
//  Copyright © 2015 Repon Macbook. All rights reserved.
//

/*
 
 *************************
 Id  : Matrix.code
 Task:
 Date:
 
 **************************
 
 */

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < (n) ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}


int len(Long n)
{
      int cnt = 0;
      while(n){
            cnt ++;
            n/=10;
      }
      return cnt;
}
class Frac {
public:
      long long a, b;
      Frac() {
            a = 0, b = 1;
      }
      Frac(long long x, long long y) {
            a = x, b = y;
            reduce();
      }
      Frac operator+(const Frac &y) {
            long long ta, tb;
            tb = this->b/gcd(this->b, y.b)*y.b;
            ta = this->a*(tb/this->b) + y.a*(tb/y.b);
            Frac z(ta, tb);
            return z;
      }
      Frac operator-(const Frac &y) {
            long long ta, tb;
            tb = this->b/gcd(this->b, y.b)*y.b;
            ta = this->a*(tb/this->b) - y.a*(tb/y.b);
            Frac z(ta, tb);
            return z;
      }
      Frac operator*(const Frac &y) {
            long long tx, ty, tz, tw, g;
            tx = this->a, ty = y.b;
            g = gcd(tx, ty), tx /= g, ty /= g;
            tz = this->b, tw = y.a;
            g = gcd(tz, tw), tz /= g, tw /= g;
            Frac z(tx*tw, ty*tz);
            return z;
      }
      Frac operator/(const Frac &y) {
            long long tx, ty, tz, tw, g;
            tx = this->a, ty = y.a;
            g = gcd(tx, ty), tx /= g, ty /= g;
            tz = this->b, tw = y.b;
            g = gcd(tz, tw), tz /= g, tw /= g;
            Frac z(tx*tw, ty*tz);
            return z;
      }
      void print()
      {
            if(b==1) {
                  printf("%lld\n", a);
            }else {
                  Long o = a/b;
                  Long d = a%b;
                  int pad = len(o);
                  int dag = len(b);
                  if(o) {
                        forn(i,pad+1) printf(" ");
                        printf("%lld\n", d);
                        printf("%lld ",o);
                        forn(i,dag) printf("-");
                        printf("\n");
                        forn(i,pad+1) printf(" ");
                        printf("%lld\n",b);
                  }else {
                        printf("%lld\n",d);
                        forn(i,dag) printf(" ");
                        printf("%lld\n",b);
                        
                  }
            }
      }
private:
      static long long gcd(long long x, long long y) {
            if(!y)  return x;
            if(x < 0)   x *= -1;
            if(y < 0)   y *= -1;
            long long t;
            while(x%y)
                  t = x, x = y, y = t%y;
            return y;
      }
      void reduce() {
            long long g = gcd(a, b);
            a /= g, b /= g;
            if(b < 0)   a *= -1, b *= -1;
      }
};
/*************************** END OF TEMPLATE ****************************/
const int N = 1001;
int n;



int main()
{
      
      
      Frac ans;
      while(scanf("%d",&n)==1) {
            ans = {0,1};
            
            
            for(int i= 1;i <=n; i ++ ) {
                  ans = ans + Frac(n,n-i+1);
            }
            ans.print();
      }
      return 0;
}

Another solution is using Principal of Inclusion-Exclusion.
The formula is :
f(n) = \dfrac{\dbinom{n}{1}}{\dfrac{1}{n}} - \dfrac{\dbinom{n}{2}}{\dfrac{2}{n}} + \dfrac{\dbinom{n}{3}}{\dfrac{3}{n}} - ......
Using this is really easy.
code :


//
//  main.cpp
//  10288 - Coupons
//
//  Created by Repon Macbook on 12/28/15.
//  Copyright © 2015 Repon Macbook. All rights reserved.
//

/*
 
 *************************
 Id  : Matrix.code
 Task:
 Date:
 
 **************************
 
 */

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < (n) ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}


int len(Long n)
{
      int cnt = 0;
      while(n){
            cnt ++;
            n/=10;
      }
      return cnt;
}
class Frac {
public:
      long long a, b;
      Frac() {
            a = 0, b = 1;
      }
      Frac(long long x, long long y) {
            a = x, b = y;
            reduce();
      }
      Frac operator+(const Frac &y) {
            long long ta, tb;
            tb = this->b/gcd(this->b, y.b)*y.b;
            ta = this->a*(tb/this->b) + y.a*(tb/y.b);
            Frac z(ta, tb);
            return z;
      }
      Frac operator-(const Frac &y) {
            long long ta, tb;
            tb = this->b/gcd(this->b, y.b)*y.b;
            ta = this->a*(tb/this->b) - y.a*(tb/y.b);
            Frac z(ta, tb);
            return z;
      }
      Frac operator*(const Frac &y) {
            long long tx, ty, tz, tw, g;
            tx = this->a, ty = y.b;
            g = gcd(tx, ty), tx /= g, ty /= g;
            tz = this->b, tw = y.a;
            g = gcd(tz, tw), tz /= g, tw /= g;
            Frac z(tx*tw, ty*tz);
            return z;
      }
      Frac operator/(const Frac &y) {
            long long tx, ty, tz, tw, g;
            tx = this->a, ty = y.a;
            g = gcd(tx, ty), tx /= g, ty /= g;
            tz = this->b, tw = y.b;
            g = gcd(tz, tw), tz /= g, tw /= g;
            Frac z(tx*tw, ty*tz);
            return z;
      }
      void print()
      {
            if(b==1) {
                  printf("%lld\n", a);
            }else {
                  Long o = a/b;
                  Long d = a%b;
                  int pad = len(o);
                  int dag = len(b);
                  if(o) {
                        forn(i,pad+1) printf(" ");
                        printf("%lld\n", d);
                        printf("%lld ",o);
                        forn(i,dag) printf("-");
                        printf("\n");
                        forn(i,pad+1) printf(" ");
                        printf("%lld\n",b);
                  }else {
                        printf("%lld\n",d);
                        forn(i,dag) printf(" ");
                        printf("%lld\n",b);
                        
                  }
            }
      }
private:
      static long long gcd(long long x, long long y) {
            if(!y)  return x;
            if(x < 0)   x *= -1;
            if(y < 0)   y *= -1;
            long long t;
            while(x%y)
                  t = x, x = y, y = t%y;
            return y;
      }
      void reduce() {
            long long g = gcd(a, b);
            a /= g, b /= g;
            if(b < 0)   a *= -1, b *= -1;
      }
};
/*************************** END OF TEMPLATE ****************************/
const int N = 1001;
int n;

Long comb[40][40];

void f()
{
      for(int i = 0; i < 34; i ++ ) {
            comb[i][0] = 1;
            for(int j = 1;j <=i; j ++ ) {
                  comb[i][j]=  comb[i-1][j] + comb[i-1][j-1];
            }
      }
}


int main()
{
      
      f();
      Frac ans;
      while(scanf("%d",&n)==1) {
            ans = {0,1};
            for(int i = 1;i <= n; i ++ ) {
                  if(i&1)ans = ans + Frac(n*comb[n][i], i);
                  else ans =ans- Frac(n*comb[n][i], i);
            }
            
            
            ans.print();
      }
      return 0;
}

The Integer (0/1) Bounded Knapsack Problem

Discussion:
From Peter’s Blog:
The Integer Bounded Knapsack Problem is :
“The bounded knapsack problem is: you are given n types of items, you have Ui items of ith type, and each item of ith type weighs Wi and costs Ci. What is the maximal cost you can get by picking some items weighing at most W in total?”

There are many Ways to solve this problem,I will show all I know.

Naive Algorithm :

for each i item, Try taking 1 of this item, 2 of this item, 3 of this item …. ui of this item, Leading a complexity of N*W*M;
where M is the mean of all Ui .


for(int i =1;i <= n; i ++ ) {
	for(int j =  W ; j>= 0; j-- ) {
		for(int t = 1; t <= U[i] ; t ++ ) {
			if(j<t*w[i] ) continue;
			dp[j] = max(dp[j] , dp[j-t*w[i]] + t* c[i]);
		}
	}
}

Improved Algorithm :
From Peter’s Blog:

The best algorithm I could find on the Internet has complexity O(W*n*log(max(ui)). It goes like this: instead of having ui items of type i, we create several new types that are multiples of type i, for example items with weight 2*wi and cost 2*ci, then the same for 4 and so on, and declare that we have just one item of each type. We create the new types in such a way that the number of new types is logarithmic, and anything that was possible to represent using the old items is also representable using the new items and vice versa. We get a 0-1 knapsack problem with n*log(max(ui) types which leads to a dynamic programming solution with the above complexity.

The illustration of this Technique is given in the following problem.
Problem Link : Link
The problem is a variant of coin-change, I need to make Lucky Number using minimum number of coins, where coins denotes the size of a disjoint tree in the graph,




#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1e5+55;
vector<int> L;
map<int,int> qq;
int dp[N];

vector< pair<int,int>  > coin;
bool vis[N];
vi G[N];
int us[N];


void dfs(int u)
{
      if(u> N) return ;
      if(u>0) L.pb(u);
      dfs(10*u+4);
      dfs(10*u+7);
      
}


int dfs(int u,int p)
{
      
      vis[u] = 1;
      int ret =0;
      for(auto a: G[u]) if(a!= p && vis[a] == 0) {
            ret += dfs(a,u);
      }
      return 1 + ret;
      
}



int main()
{
      dfs(0);
      DII(n,m);
      forn(i,m){
            DII(a,b);
            G[a].pb(b);
            G[b].pb(a);
      }
      
      for(int i =1; i<= n; i ++ ) {
            if(vis[i] == 0 ) {
                  int t = dfs(i,-1);
                  qq[t] ++;
            }
      }
      
      for(auto a: qq) {
            //   Partitioning The Ui into several individual components
            int x = a.first;
            int y = a.second;
            for(int i = 1; i <= y ; y-= i, i*=2){
                  coin.pb(mp(x*i,i));
            }
            if(y>0)coin.pb(mp(x*y,y));
      }
      sort(all(coin)); // This is necessary .. Tell me why ??
      for(int i = 0;i < N; i++ ) dp[i] = INF;
      dp[0] = 0;
      int tot = 0;
      for(auto a : coin){
            tot += a.first;
            for(int j = tot; j >= a.first; j -- ) {
                  dp[j] = min(dp[j] , dp[j - a.first] + a.second);
            }
      }
      int iM = INF;
      for(auto a: L) iM = min(iM, dp[a]);
      printf("%d\n", iM == INF ? -1 : iM -1);
      
}

For O(n*W) complexity:

First, we start with the standard dynamic programming solution: let dpk,w be the best cost that we can get by packing the total weight of w using the first k item types. Each new type is then handled as follows: dpk,w=min(dpk-1,w, dpk-1,w-wk+ck, …, dpk-1,w-uk*wk+uk*ck). This dynamic programming has O(W*n) states, and each state is processed in O(max(ui)).

But we can process each state in O(1) amortized time! Let’s take a look at the above recurrence. First, we notice that we can separate all values of w into wk groups, based on the remainder of division on wk, and those groups can be handled separately. Then, for each group, the problem we need to solve is to find min(ai, ai-1+c, ai-2+2*c, …, ai-k+k*c). By setting bi=ai-i*c, this expression is transformed into min(bi+i*c,bi-1+(i-1)*c+c, …), which is just i*c+min(bi, bi-1, …, bi-k). Thus our problem is reduced to finding minimums of groups of k+1 consecutive numbers in a given array. And this, in turn, is a well-known problem that is solvable in O(size of array) using one of the two methods: we can either maintain a sequence of incremental (from the end) minima for a segment of size k+1 and update it quickly when we shift one position to the right, or we can just separate the entire array into blocks of size k+1, and calculate the prefix and suffix minima for each block – this allows to find the minimum for any block of size k+1 by splitting it into two blocks with precomputed answers.

CODE will be given later.

Related Problem :
Link : Problem

Josephus problem

From : Rosetta

Josephus problem is a math puzzle with a grim description: n prisoners are standing on a circle, sequentially numbered from 0 to n − 1.

An executioner walks along the circle, starting from prisoner 0, removing every k-th prisoner and killing him.

As the process goes on, the circle becomes smaller and smaller, until only one prisoner remains, who is then freed.
For example, if there are n = 5 prisoners and k = 2, the order the prisoners are killed in (let’s call it the “killing sequence”) will be 1, 3, 0, and 4, and the survivor will be #2.

Task Given any n,k > 0, find out which prisoner will be the final survivor. In one such incident, there were 41 prisoners and every 3rd prisoner was being killed (k = 3). Among them was a clever chap name Josephus who worked out the problem, stood at the surviving position, and lived on to tell the tale. Which number was he?

How To solve ?

There are n people in a circle, and people counts from 1 to k, and the person who count k will be eliminated. And we keep this process until there is only 1 person left in the circle.

Let’s first number position of these n people: 0, 1, 2, …, n-1. You notice that we change number from [1,2…n] to [0,1,…n-1], this is because of module operation. Likewise, people will now count from 0 to k-1, and the person who count k-1 will be eliminated.

The first person to be eliminated is in position (k-1)%n. After the first person has been eliminated, the circle now has only n-1 people left. One key discovery is that the last person who is finally eliminated(we call him lucky guy) is the same one to be eliminated in n-1 people circle!

Now we begin eliminate the second person:

Since (k-1)%n is the position that the first person got eliminated, then k%n must be the 0-th position for this round.

So we can number accordingly in the following table:

Position in first round ———-Position in second round
k%n ——————————— 0
k%n+1 ——————————- 1
k%n+2 ——————————- 2

….

Let’s assume the lucky guy in the first round in position: f(n, k).
Then the same lucky guy in the second round in position: f(n-1, k)

So, based on the table, we know the lucky guy in second round who is in position f(n-1, k), must be in position k%n+f(n-1,k) in the first round.

Position in first round ———-Position in second round
k%n ———————————- 0
k%n+1 ——————————– 1
k%n+2 ——————————– 2

k%n+f(n-1,k) ——————- f(n-1,k)

So, we know f(n,k) = k%n + f(n-1,k), to avoid over the range, we make it f(n,k) = (k%n + f(n-1,k)) % n = (k + f(n-1,k)) %n

Base Case : f(1,k) = 0;

Courtesy : Billionaire

Special Case :
k = 2,
We explicitly solve the problem when every 2nd person will be killed, i.e. k=2. We express the solution recursively. Let f(n) denote the position of the survivor when there are initially n people (and k=2). The first time around the circle, all of the even-numbered people die. The second time around the circle, the new 2nd person dies, then the new 4th person, etc.; it’s as though there were no first time around the circle.
If the initial number of people was even, then the person in position x during the second time around the circle was originally in position 2x – 1 (for every choice of x). Let n=2j. The person at f(j) who will now survive was originally in position 2f(j) – 1. This gives us the recurrence
f(2j)=2f(j)-1 ;.
If the initial number of people was odd, then we think of person 1 as dying at the end of the first time around the circle. Again, during the second time around the circle, the new 2nd person dies, then the new 4th person, etc. In this case, the person in position x was originally in position 2x+1. This gives us the recurrence
f(2j+1)=2f(j)+1 ;.

Problem : Problem

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 2005;
char st[10];

int calc(int n)
{
      if(n==1) return 1;
      if(n%2==0) return 2*calc(n/2) - 1;
      else return 2 * calc(n/2) + 1;
}
int main()
{
      while(1){
            scanf("%s",st);
            int n = (st[0] -'0') * 10 + st[1]-'0';
            int p = st[3] -'0';
            for(int i = 0; i<p;i++ ) n*=10;
            if(n==0) break;
            
            cout<< calc(n) << endl;
            
      }
      
}

Here Problem List
1. Musical Chairs
2. WTK
3. King</a
4.
UVA-10774

Geometry – Check if a Line segment intersect a circle or not ??

Intended Problem : Link
Solution : Tutorial

Discussion :

We will try to find whether the line segment `AB` intersects with the circle with center `C` and radius `r`.

It’s helpful to think of ‘A’ and ‘B’ as vectors, which you can scale, and add with other vectors. Thus, we can think of the line segment \xrightarrow { AB } as the set of points `P` such that:
P=A+(B-A)t

for some 0<= t <= 1 , and the circle with center `C` and radius `r` as the set of points `P` such that:
\sqrt { (P-C)\cdot (P-C) } =r

where `⋅` is the dot product (it is known that the length of a vector `V` is given by  \sqrt { V\cdot V } ).

Now we are trying to find a point `P` that belongs to both sets of points, so we substitute
 P=A+(B-A)t to the circle formula and manipulate to get:
Snip20150910_2

Snip20150910_3

There can be two, one, or no roots `t` (depending on the sign of the determinant `β2−αγ`). We simply check whether one of them is in the range `0≤t≤1`, and if so, we say that the segment intersects the circle!


In our intended Problem We need to handle Three edge of the triangle . If anyone of them intersect The circle Than Ans = "YES"
Or Ans = "NO"

Now code :



#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;scanf("%d",&n)
#define DII(a,b)                int a,b;scanf("%d %d",&a,&b)
#define DIII(a,b,c)             int a,b,c;scanf("%d %d %d",&a,&b,&c)

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
inline void sc(int &x){
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}
template <class T> inline T bigmod(T p,T e,T M){
	LL ret = 1;
	for(; e > 0; e >>= 1){
		if(e & 1) ret = (ret * p) % M;
		p = (p * p) % M;
	} return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
double INF = 1e100;
double EPS = 1e-12;


struct PT {
      LL  x,y;
      PT(double x=0, double y=0) : x(x), y(y) {}
      PT(const PT &p) : x(p.x), y(p.y)    {}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y);}
      PT operator * (double c) const { return PT(x*c,y*c);}
      PT operator / (double c) const { return PT(x/c,y/c);}
      void in(){scanf("%lld %lld",&x,&y);}
};

LL dot(PT p,PT q){ return p.x * q.x + p.y * q.y;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
LL dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

// rotate a point CCW or CW around the origin
PT RotCCW90(PT p){return PT(-p.y,p.x);}
PT RotCW90(PT p)   {return PT(p.y,-p.x);}
PT RotCCW(PT p,double ang) {return PT(p.x*cos(ang) - p.y*sin(ang) , p.x*sin(ang) + p.y * cos(ang));}

// project point c onto line through a and b
PT PPL (PT a,PT b,PT c){return a + (b-a)* dot(c-a,b-a) / dot(b-a,b-a);}

// project point c onto line segment through a and b
PT PPS(PT a, PT b, PT c) {
      double r = dot(b-a,b-a);
      if (fabs(r) < EPS) return a;
      r = dot(c-a, b-a)/r;
      if (r < 0) return a;
      if (r > 1) return b;
      return a + (b-a)*r;
}
// compute intersection of line through points a and b with
// circle centered at c with radius r > 0

vector<PT> CLIN(PT a, PT b, PT c, double r) {
      vector<PT> ret;
      b = b-a;
      a = a-c;
      double A = dot(b, b);
      double B = dot(a, b);
      double C = dot(a, a) - r*r;
      double D = B*B - A*C;
      if (D < -EPS) return ret;
      ret.push_back(c+a+b*(-B+sqrt(D+EPS))/A);
      if (D > EPS)
            ret.push_back(c+a+b*(-B-sqrt(D))/A);
      return ret;
}
/*************************** END OF TEMPLATE ****************************/
const int N = 2005;

PT O;
PT a,b,c;
LL r;

bool check(PT a, PT b)
{
      LL alp = dot(b-a,b-a);
      LL beta = dot(b-a,a-O);
      LL gama = dot(a-O,a-O) - r * r ;
      
      if(alp==0){
            if(beta) {
                  double t = -(double) gama/(2*beta);
                  if(t>=0 && t<= 1) return true;
            }else return false;
      }
      else {
            if(beta*beta-gama*alp>=0 ) {
                  double e1  = (-beta + sqrt(beta*beta-gama*alp) )/ alp;
                  double e2 = (-beta - sqrt(beta*beta-gama*alp) )/ alp;
                  if((e1>=0&&e1<=1) || (e2>=0 &&e2<=1) ) return 1;
                  return 0;
            }
            else return 0;
      }
      return 0;
}

int main()
{
      DI(tc);
      while(tc--){
            
            
            O.in();
            cin >> r;
            a.in();
            b.in();
            c.in();
            
            bool flag = 0;
            if(check(a,b) || check(b,c) || check(a,c) ) {
                  flag = 1;
            }
            
            printf("%s\n" , flag ? "YES" : "NO");
      }
      
}

Cayley’s Formula

Discussion : for every positive integer n, the number of trees on n labeled vertices is n^{n-2}.
For proof : http://www.math.uchicago.edu/~may/VIGRE/VIGRE2006/PAPERS/Casarotto.pdf
Problem Link : 10843 – Anne’s game
Solution :



#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define show(Ara,N)             for(int i = 0; i < N;i ++ ) printf("%d -> %d\n" , i , Ara[i])

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}
template <class T> inline T bigmod(T p,T e,T M){
	LL ret = 1;
	for(; e > 0; e >>= 1){
		if(e & 1) ret = (ret * p) % M;
		p = (p * p) % M;
	} return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 100;


int main()
{
      
      DI(tc);
      int cs= 0;
      while(tc--){
            LL a;
            scanf("%lld",&a);
            if(a==1){
                  printf("Case #%d: %d\n",  ++cs , 1);
                  continue;
            }
            printf("Case #%d: %lld\n", ++cs , bigmod(a,a-2,2000000011LL));
      }
      return 0;
}


Geometry – Finding Minimum Width of a Set of points

Problem Link : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=3552

Method : Convex Hull, Rotating Clipper


#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define show(Ara,N)             for(int i = 0; i < N;i ++ ) printf("%d -> %d\n" , i , Ara[i])

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}
template <class T> inline T bigmod(T p,T e,T M){
	LL ret = 1;
	for(; e > 0; e >>= 1){
		if(e & 1) ret = (ret * p) % M;
		p = (p * p) % M;
	} return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 105;
typedef long double LLDD;
LLDD INF = 1e100;
LLDD EPS = 1e-12;


struct PT {
      LLDD  x,y;
      PT(){}
      PT(LLDD x, LLDD y) : x(x), y(y) {}
      PT(const PT &p) : x(p.x), y(p.y)    {}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y);}
      PT operator * (LLDD c) const { return PT(x*c,y*c);}
      PT operator / (LLDD c) const { return PT(x/c,y/c);}
      
}P[N];

LLDD dot(PT p,PT q){ return p.x * q.x + p.y * q.y;}
LLDD cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
LLDD dist2(PT p,PT q) {return dot(p-q , p-q);}
LLDD DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

// rotate a point CCW or CW around the origin
PT RotCCW90(PT p){return PT(-p.y,p.x);}
PT RotCW90(PT p)   {return PT(p.y,-p.x);}
PT RotCCW(PT p,LLDD ang) {return PT(p.x*cos(ang) - p.y*sin(ang) , p.x*sin(ang) + p.y * cos(ang));}

// project point c onto line through a and b
PT PPL (PT a,PT b,PT c){return a + (b-a)* dot(c-a,b-a) / dot(b-a,b-a);}

// project point c onto line segment through a and b
PT PPS(PT a, PT b, PT c) {
      LLDD r = dot(b-a,b-a);
      if (fabs(r) < EPS) return a;
      r = dot(c-a, b-a)/r;
      if (r < 0) return a;
      if (r > 1) return b;
      return a + (b-a)*r;
}
PT pivot;
bool cmp(PT a, PT b)
{
      LLDD d = cross(a-pivot,b-pivot);
      if(d>0) return 1;
      else if(d<0)return 0;
      else {
            LLDD d1 = dist2(pivot,a);
            LLDD d2 = dist2(pivot,b);
            return d1<d2;
      }
}
vector<PT> Hul;

void CH(PT P[] , int SZ)
{
      LLDD iy = INF ;
      int id = -1;
      for(int i= 0;i < SZ; i ++ ) {
            if(P[i].y < iy){
                  iy = P[i].y, id = i;
            }
      }
      swap(P[0],P[id]);
      pivot = P[0];
      
      sort(P,P+SZ, cmp);
      Hul.pb(P[0]);
      Hul.pb(P[1]);
      for(int i = 2;i < SZ ; i++ ) {
            while(Hul.size() > 1 && cross(Hul[Hul.size() - 1] - Hul[Hul.size() -2 ] , P[i] - Hul[Hul.size()-1] ) <= 0 ) Hul.pop_back();
            Hul.pb(P[i]);
      }
      
}

LLDD PPLDIS(PT a, PT b, PT c)
{
      PT d = PPL(a,b,c);
      return sqrt(dist2(c,d));
}

LLDD MiniMumBoundingBox(vector<PT> & v )
{
      
      int sz = (int)v.size();
      int aI =0 ,bI = 0;
      for(int i=1;i<sz;i++){
            if(v[i].y < v[aI].y) aI = i;
            if(v[i].y > v[bI].y) bI = i;
      }
      
      LLDD ans = v[bI].y - v[aI].y;
      LLDD ang1,ang2;
      PT aV = {1,0}, bV={-1,0};
      
      for(LLDD ang = 0; ang <= PI ; ang += min(ang1,ang2)){
            ang1 = acos( dot( v[(aI+1)%sz] - v[aI] , aV) / DIM(v[(aI+1)%sz] -v[aI]) / DIM(aV));
            ang2 = acos( dot( v[(bI+1)%sz] - v[bI] , bV) / DIM(v[(bI+1)%sz] - v[bI]) / DIM(bV));
            aV = RotCCW(aV,min(ang1,ang2));
            bV = RotCCW(bV,min(ang1,ang2));
            if(ang1 < ang2 ){
                  ans = min( ans , PPLDIS(v[aI],v[aI] + aV , v[bI]));
                  aI= (aI+1) %sz;
            }
            else {
                  ans = min( ans , PPLDIS(v[bI], v[bI] + bV, v[aI]));
                  bI = (bI+1)%sz;
            }
            
            
      }
      return ans;
      
}

int main()
{
      int cs = 0;
      while(1){
            DI(n);
            if(!n) break;
            forn(i,n){
                  DII(x,y);
                  P[i].x= x;
                  P[i].y=y;
            }
            CH(P,n);
            
            printf("Case %d: %.2Lf\n", ++cs , MiniMumBoundingBox(Hul));
            Hul.clear();
            
      }
      
}


Geometry – Convex Hull

Problem Link : http://lightoj.com/volume_showproblem.php?problem=1203

Method: Graham Scan


#include <bits/stdc++.h>
using namespace std;
 
/*------- Constants---- */
 
#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;scanf("%d",&n)
#define DII(a,b)                int a,b;scanf("%d %d",&a,&b)
#define DIII(a,b,c)             int a,b,c;scanf("%d %d %d",&a,&b,&c)
 
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
inline void sc(int &x){
    register int c = gc();
    x = 0;
    int neg = 0;
    for(;((c<48 | c>57) && c != '-');c = gc());
    if(c=='-') {neg=1;c=gc();}
    for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
    if(neg) x=-x;
}
template <class T> inline T bigmod(T p,T e,T M){
    LL ret = 1;
    for(; e > 0; e >>= 1){
        if(e & 1) ret = (ret * p) % M;
        p = (p * p) % M;
    } return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
template <class T > inline void extEuclid(T  a, T b, T &x, T &y, T &gcd) {
      x = 0; y = 1; gcd = b;
      T m, n, q, r;
      for (T u=1, v=0; a != 0; gcd=a, a=r) {
            q = gcd / a; r = gcd % a;
            m = x-u*q; n = y-v*q;
            x=u; y=v; u=m; v=n;
      }
}
 
// The result could be negative, if it's required to be positive, then add "m"
template <class T > inline T  modInv(T n, T m) {
      T x, y, gcd;
      extEuclid(n, m, x, y, gcd);
      if (gcd == 1) return x % m;
      return 0;
}
 
/*************************** END OF TEMPLATE ****************************/
const int N = 1e5+55;
const double INF  = 1e18;
struct PT{
      double x,y;
      PT operator + (const PT &q) {return {x+q.x,y+q.y};}
      PT operator - (const PT &q) {return {x-q.x,y-q.y};}
      PT operator * (double c   ) {return {x*c,y*c};    }
      PT operator / (double c  ) {return {x/c,y/c};}
}P[N];
double sqr(double a){return a*a;}
double dist2(PT a, PT b) {return sqr(a.x-b.x) + sqr(a.y-b.y);}
double dot(PT a,PT b) {return a.x*b.x+a.y*b.y;}
double cross(PT a,PT b){return a.x*b.y-a.y*b.x;}
double DIM(PT a) {return sqrt(a.x*a.x+a.y*a.y);}
 
 
PT pivot;
bool cmp(PT a, PT b)
{
      double d = cross(a-pivot,b-pivot);
      if(d>0) return 1;
      else if(d<0)return 0;
      else {
            double d1 = dist2(pivot,a);
            double d2 = dist2(pivot,b);
            return d1<d2;
      }
}
vector<PT> Hul;
 
void CH(PT P[] , int SZ)
{
      double iy = INF ;
      int id = -1;
      for(int i= 0;i < SZ; i ++ ) {
            if(P[i].y < iy){
                  iy = P[i].y, id = i;
            }
      }
      swap(P[0],P[id]);
      pivot = P[0];
     
      sort(P,P+SZ, cmp);
      Hul.pb(P[0]);
      Hul.pb(P[1]);
      for(int i = 2;i < SZ ; i++ ) {
            while(Hul.size() > 1 && cross(Hul[Hul.size() - 1] - Hul[Hul.size() -2 ] , P[i] - Hul[Hul.size()-1] ) <= 0 ) Hul.pop_back();
            Hul.pb(P[i]);
      }
     
}
 
 
int main()
{
     
      DI(tc);
      int cs = 0;
      while(tc--){
            DI(n);
            forn(i,n){
                  DII(a,b);
                  P[i].x = a , P[i].y = b;
            }
            if(n<3){
                  printf("Case %d: 0\n", ++cs);
                  continue;
            }
            else {
                  CH(P,n);
                  int sz = Hul.size();
                  if(sz < 3) {
                        printf("Case %d: 0\n", ++cs);
                  }
                  else {
                  double ans = 2*PI;
                  for(int i = 0; i < sz; i ++ ) {
                        PT ab = Hul[(i-1+sz) % sz] - Hul[i];
                        PT bc = Hul[(i+1)%sz] - Hul[i];
                       
                        double d = dot(ab,bc);
                        d/= (DIM(ab)*DIM(bc));
                        double a = acos(d);
                        ans = min(ans,a);
                  }
               
                  printf("Case %d: %.9lf\n", ++cs , 180*ans/PI);
                  }
            }
            Hul.clear();
      }
     
      return 0;
}

জ্যামিতি

আমি নিজেই জ্যামিতি অত ভাল পারি না । তাই এ নিয়ে একটু পড়ি আর লিখি । এই লেখার জন্যে অনেক কিছু পড়তে হয় । এতেই বহুত জ্ঞান ।
আমি এখানে বেশ কিছু টাইপের বিগিনার জ্যামিতি প্রব্লেম গুলো নিয়ে লিখব ।

প্রব্লেম ১ ঃ
লাইট অজিতে জ্যামিতির যে প্রব্লেম টা সবচেয়ে বেশি শলভ হয়েছে সেটি
লিঙ্ক ঃ http://lightoj.com/volume_showproblem.php?problem=1022
http://lightoj.com/volume_showproblem.php?problem=1022
প্রব্লেম টাতে চেয়েছে ঃ একটা Circle আর ব্যাসের সমান বাহুবিশিষ্ট একটা বর্গের ক্ষেত্রফল – ওই Circle এর ক্ষেত্রফল
এখন circle এর ব্যাসার্ধ r হলে ,ব্যাস 2r , বর্গের ক্ষেত্রফল (2r)^2
আর ওই circle এর ক্ষেত্রফল PI * r^2;

#include <stdio.h>
#include <math.h>
int main()
{
 
    int testcase,i;
    scanf("%d",&testcase);
    double radius;
    for (i=1;i<=testcase; i++) {
        scanf("%lf",&radius);
        printf("Case %d: %.2lf\n",i,(4*radius*radius)-2*acos(0.0)*radius*radius);
    }
    return 0;
}

Hashing With Application

Hashing is very important for competitive programming. Normally,what we do in hashing is ,We compress the whole structure (string, may be an array) to a single number..(hash_value)..
Okay, All the different structure should have different hash value, To compute hash_value, we need a hash function that is computes a unique hash value for each..


Let assume A={1,2,3,4} , B= {1,2,3,3}, C = {1,2,3,4,5} , D ={1,2,3,4};
Than getHash(A) should be equal to getHash(D) as they are same. Same rules apply for String

Constructing a hash function is very simple


Step 1: Choose A prime as mod ,typically I use P = 1e7 + 7
Step 2: Choose A prime as base value (which need to greater than in entries of the structure) For String I use B = 131
Step 3: Using hornar’s rule , calculate H

Here it is :
This is shown for string, same rule applicable for vector, array
Okay, I use Polynomial representation of vector
Here h = s[0] * B^(n-1) + s[1] * B^(n-2) + S[2] * B^(n-3) ….. + S[n-1] * B^0

long long getHash(string s)
{
	long long h = 0;
	for(int i = 0 ; s[i]; i ++ ){
		h = (h * B + s[i]) % P;
	}
	return h;
}

This hash_value is stored in a map … or set what you like to use which supports find or count operation…

Now I illustrate a simple problem with hashing

Problem : http://codeforces.com/contest/4/problem/C

Abridge statement: Given N strings, One by one, Process them ,
* If they have not occurred previously ,then print ‘OK’
* Else Print “The string + Previously occurred how many times”

Solution:

1. for each string , We compute its hash value ,Then check if it is already in the map ??
2. If yes, Then print The string + The number of times it occurred previously,
3. Else print NO


#include <bits/stdc++.h>
#include <cstring>
using namespace std;

/*------- Constants---- */
#define LMT                     15
#define ll                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define FOR(i,n)                for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define GREATER(x, y)           ((x) > (y) + EPS)
#define GREATER_EQUAL(x, y)     ((x) > (y) - EPS)
#define LESS(x, y)              ((x) < (y) - EPS)
#define LESS_EQUAL(x, y)        ((x) < (y) + EPS)
#define EQUAL(x, y)             (abs((x) - (y)) < EPS)
#define msg(x)                  cout << x << endl

/* -------Global Variables ------ */
ll euclid_x,euclid_y,d;

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */

inline void sc(int &x)
{
      
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}

template <class T> inline T bigmod(T p,T e,T M){
      ll ret = 1;
      for(; e > 0; e >>= 1){
            if(e & 1) ret = (ret * p) % M;
            p = (p * p) % M;
      } return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/





string str;

map<ll , int> kmp;
ll B = 131;
ll P = 1e7 + 7;


long long getHash(string s)
{
	long long h = 0;
	for(int i = 0 ; s[i]; i ++ ){
		h = (h * B + s[i]) % P;
	}
	return h;
}


int main()
{
      
      int n;
      
      
      sc(n) ;
      
      for(int i = 0 ; i < n ; i ++ ) {
            cin >> str;
            ll k = getHash(str);
            if( kmp.count(k) == 0 ) {
                  printf("OK\n");
            }
            else {
                  cout << str ;
                  printf("%d\n",kmp[k]);
            }
            kmp[k] ++;
            
      }
      
      return 0;
}

Yaahhh..
This is a wrong code… Why ?? Because My hash function is simple but it is producing some collision. So we need a way out…
1. if two strings have same length, Then the probability of collision is very very small. So we can do , We use a length wise map…

2.Use double hashing

3. Others ,I don’t know

Approach 1:
In the above solution we were using one map, But now we will use an array of map..
How many Map I need? Maximum Length

So This is an accepted code:


#include <bits/stdc++.h>
#include <cstring>
using namespace std;

/*------- Constants---- */
#define LMT                     15
#define ll                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define FOR(i,n)                for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define GREATER(x, y)           ((x) > (y) + EPS)
#define GREATER_EQUAL(x, y)     ((x) > (y) - EPS)
#define LESS(x, y)              ((x) < (y) - EPS)
#define LESS_EQUAL(x, y)        ((x) < (y) + EPS)
#define EQUAL(x, y)             (abs((x) - (y)) < EPS)
#define msg(x)                  cout << x << endl

/* -------Global Variables ------ */
ll euclid_x,euclid_y,d;

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */

inline void sc(int &x)
{
      
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}

template <class T> inline T bigmod(T p,T e,T M){
      ll ret = 1;
      for(; e > 0; e >>= 1){
            if(e & 1) ret = (ret * p) % M;
            p = (p * p) % M;
      } return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/





string str;

map<ll , int> kmp[LMT];
ll B = 131;
ll P = 1e7 + 7;


long long getHash(string s)
{
	long long h = 0;
	for(int i = 0 ; s[i]; i ++ ){
		h = (h * B + s[i]) % P;
	}
	return h;
}


int main()
{
      
      int n;
      
      
      sc(n) ;
      
      for(int i = 0 ; i < n ; i ++ ) {
            cin >> str;
            ll k = getHash(str);
            if( kmp[str.length()].count(k) == 0 ) {
                  printf("OK\n");
            }
            else {
                  cout << str ;
                  printf("%d\n",kmp[str.length()][k]);
            }
            kmp[str.length()][k] ++;
            
      }
      
      return 0;
}

Approach 2: Double Hashing
We use Two mod instead of 1.
so now P1 = 1e7+7 , P2 = 1e9+9;
now store pair of values for them,,

Here is the code



#include <bits/stdc++.h>
#include <cstring>
using namespace std;

/*------- Constants---- */
#define LMT                     15
#define ll                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define FOR(i,n)                for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define GREATER(x, y)           ((x) > (y) + EPS)
#define GREATER_EQUAL(x, y)     ((x) > (y) - EPS)
#define LESS(x, y)              ((x) < (y) - EPS)
#define LESS_EQUAL(x, y)        ((x) < (y) + EPS)
#define EQUAL(x, y)             (abs((x) - (y)) < EPS)
#define msg(x)                  cout << x << endl

/* -------Global Variables ------ */
ll euclid_x,euclid_y,d;

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */

inline void sc(int &x)
{
      
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}

template <class T> inline T bigmod(T p,T e,T M){
      ll ret = 1;
      for(; e > 0; e >>= 1){
            if(e & 1) ret = (ret * p) % M;
            p = (p * p) % M;
      } return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/





string str;

map<pair<ll, ll>, int > kmp;
ll B = 131;
ll P1 = 1e7 + 7;
ll P2 = 1e9+9;

pair<ll , ll>  getHash(string s)
{
	long long h1 = 0 , h2 = 0;
	for(int i = 0 ; s[i]; i ++ ){
		h1 = (h1 * B + s[i]) % P1;
            h2 = (h2 * B + s[i]) % P2;
	}
	return mp(h1,h2);
}


int main()
{
      
      int n;
      
      
      sc(n) ;
      
      for(int i = 0 ; i < n ; i ++ ) {
            cin >> str;
            pair<ll, ll> k = getHash(str);
            if( kmp.count(k) == 0 ) {
                  printf("OK\n");
            }
            else {
                  cout << str ;
                  printf("%d\n",kmp[k]);
            }
            kmp[k] ++;
            
      }
      
      return 0;
}

We will discuss some other problem in other day 🙂

KMP , Minimum Length of a Repeated String

KMP algorithm quickly finds the minimum length of a substring which is repeated N >=1 times to make the whole string..
An example :
S : ababab
S can be writen as ab * ab * ab where * means concatenation.
So minimal length is 2(ab)

Another example :
S : abababab
S can be writen as abab * abab but which gives a length of 4,,
But S can also be written as ab * ab *ab * ab which gives result 2…

Another :
S : prime
There is no way we can fragment it,, Minimal length = 5

This is the question
Now How we can use kmp to compute minimal length

This will be clear at with this discussion:

S : abcabc

We find it’s Prefix_function

S : a b c a b c
Pi: 0 0 0 1 2 3

Okay : Another

S : a b a b a b
Pi: 0 0 1 2 3 4

Another :

S : a a a a
Pi: 0 1 2 3

Another :

S : a b c d a b c a b c d
Pi: 0 0 0 0 1 2 3 1 2 3 4

From this examples,,, You can see that , For a repeated String , The last entries are 1,2,3,… increasing by 1
For second example :
The last value of prefix table = 4..
Now If it is a repeated string than , It’s minimal length would be 2. (6(string length) – 4) , Now how many time it is concatenated ?
string_length / minimal_length

Furthur checking :

if( minimal_length * times == string_length) :
      "YES, IT's A Repeated String" and Minimal Length = minimal_length
else :
      Minimal Length = string_length

This Method Can be used to solve UVA – 10298
This only requires to find how many times…the string is concatenated??

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */
#define LMT                     1000006
#define ll                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define FOR(i,n)                for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define msg(x)			  cout<<x<<endl;

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
inline void sc(int &x)
{
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}

template <class T> inline T bigmod(T p,T e,T M){
	ll ret = 1;
	for(; e > 0; e >>= 1){
		if(e & 1) ret = (ret * p) % M;
		p = (p * p) % M;
	} return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/

char P[LMT];
int pi[LMT];

int  prefix_function(char pattern[] , int psize)
{
	
	pi[0] = 0;
	for(int i = 1; i < psize; i ++ ) {
		
		int j = pi[i-1];
		
		while (j > 0 && pattern[j] != pattern[i] ) {
			
			j  = pi[j-1];
		}
		if( pattern[i] == pattern[j ] ) ++ j;
		pi[i ] = j ;
	}
	
	return pi[psize - 1];
}

int main()
{
	
	
	while (scanf("%s",P )) {
		if(P[0] =='.') break;
		int l = (int) strlen(P);
		int k = prefix_function(P, l);
		int in = l - k;
		int N = l / in;
		
		if( in * N == l ) {
			printf("%d\n", N);
		}
		else printf("1\n");
	}
	return 0;
}

Another Hard(:P) Problem That requires this Technique along with DP..
UVA – 11022

This is a dp problems . Where sub-problems are the sub-strings…

In dp table , we store minimum cost of substring S[i...j]

for every substring S[i...j],  We can check if it's a repeated string or not ,.
If it is :
       L = minimum length of repeated string
       dp[i][j] =  minimum cost for minimum repeated string( S[i,...., L-1])
else : 
      //we partition the substring into two substring
      int iMin = inf;
      for(int k = i; k &lt;j ; k ++ ) {
             int t = cost(i,k) + cost(k+1,j)
             iMin = min(iMin , t)
      }
//Save the value in dp Table

Here is the code


#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */
#define LMT				100
#define ll				long long
#define ull				unsigned long long
#define mod				1000000007
#define MEMSET_INF		63
#define MEM_VAL			1061109567
#define FOR(i,n)			for( int i=0 ; i < n ; i++ )
#define mp(i,j)			make_pair(i,j)
#define lop(i,a,b)		for( int i = (a) ; i < (b) ; i++)
#define pb(a)			push_back((a))
#define gc				getchar_unlocked
#define PI				acos(-1.0)
#define inf				1<<30
#define lc				((n)<<1)
#define rc				((n)<<1 |1)
#define msg(x)			cout<<x<<endl;

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
inline void sc(int &x)
{
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}

template <class T> inline T bigmod(T p,T e,T M){
	ll ret = 1;
	for(; e > 0; e >>= 1){
		if(e & 1) ret = (ret * p) % M;
		p = (p * p) % M;
	} return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/

string S;
int dp[LMT][LMT];

int prefix_function(string s)
{
	int pi[LMT];
	pi[0] = 0;
	for (int i = 1 ; i < s.length() ; i ++ ) {
		int j = pi[i-1];
		while (j > 0 && s[i] != s[j])  {
			j  = pi[j-1];
		}
		if(s[i] == s[j] ) ++j;
		pi[i] = j;
	}
	int in = s.length() - pi[s.length()-1];
	int N = s.length()/ in;
	if(in*N == s.length() ) {
		return in;
	}
	else return s.length();
	
}
int cal(int i , int j)
{
	if( i == j ) {
		return 1;
	}
	
	if(dp[i][j] !=-1 ) return dp[i][j];
	
	int lengthOfRepeatedSequence = prefix_function(S.substr( i , j - i + 1) );
	if(lengthOfRepeatedSequence == j-i+1){
		int iM = inf;
		for (int  k =  i ; k < j ; k ++ ) {
			int t = cal(i , k) + cal( k + 1 , j );
			if( t < iM) iM = t;
		}
		dp[i][j] = iM;
	}
	else {
		dp[i][j] = cal(i , i + lengthOfRepeatedSequence - 1);
	}
	
	
	return dp[i][j];
}
int main()
{
	
	while (cin >> S ) {
		if(S.compare("*") == 0 ) break;
		ms(dp, -1);
		int p = cal(0 , S.length() -1) ;
		printf("%d\n" , p);
	}
	
	return 0;
}