Thursday, 3 March 2016

**RMQ USING SPARCE TABLE

Sparse Table (ST) algorithm
A better approach is to preprocess RMQ for sub arrays of length 2k using dynamic programming. We will keep an array M[0, N-1][0, logN] where M[i][j] is the index of the minimum value in the sub array starting at ihaving length 2j. Here is an example:
For computing M[i][j] we must search for the minimum value in the first and second half of the interval. It’s obvious that the small pieces have 2j – 1 length, so the recurrence is:
The preprocessing function will look something like this:
  void process2(int M[MAXN][LOGMAXN], int A[MAXN], int N)
  {
      int i, j;
   
  //initialize M for the intervals with length 1
      for (i = 0; i < N; i++)
          M[i][0] = i;
  //compute values from smaller to bigger intervals
      for (j = 1; 1 << j <= N; j++)
          for (i = 0; i + (1 << j) - 1 < N; i++)
              if (A[M[i][j - 1]] < A[M[i + (1 << (j - 1))][j - 1]])
                  M[i][j] = M[i][j - 1];
              else
                  M[i][j] = M[i + (1 << (j - 1))][j - 1];
  }  
Once we have these values preprocessed, let’s show how we can use them to calculate RMQA(i, j). The idea is to select two blocks that entirely cover the interval [i..j] and  find the minimum between them. Let k = [log(j - i + 1)]. For computing RMQA(i, j) we can use the following formula:
So, the overall complexity of the algorithm is <O(N logN), O(1)>.

LCA - Lowest Common Ancestor(spoj checked)( both binary rais and seg tree)

LCA - Lowest Common Ancestor

no tags 

A tree is an undirected graph in which any two vertices are connected by exactly one simple path. In other words, any connected graph without cycles is a tree. - Wikipedia 
The lowest common ancestor (LCA) is a concept in graph theory and computer science. Let T be a rooted tree with N nodes. The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself). - Wikipedia
Your task in this problem is to find the LCA of any two given nodes v and w in a given tree T.

For example the LCA of nodes 9 and 12 in this tree is the node number 3.

Input

The first line of input will be the number of test cases. Each test case will start with a number N the number of nodes in the tree, 1 <= N <= 1,000. Nodes are numbered from 1 to N. The next N lines each one will start with a number M the number of child nodes of the Nth node, 0 <= M <= 999 followed by M numbers the child nodes of the Nth node. The next line will be a number Q the number of queries you have to answer for the given tree T, 1 <= Q <= 1000. The next Q lines each one will have two number v and w in which you have to find the LCA of v and w in T, 1 <= v, w <= 1,000.
Input will guarantee that there is only one root and no cycles.

Output

For each test case print Q + 1 lines, The first line will have “Case C:” without quotes where C is the case number starting with 1. The next Q lines should be the LCA of the given v and w respectively.

Example

Input:
1
7
3 2 3 4
0
3 5 6 7
0
0
0
0
2
5 7
2 7

Output:
Case 1:
3
1
//  node of the tree is 1 based index so if in any problem nodes are 
// 0 based than make it 1 based by increasein 1 each node while 
// makin graph , also at  the time of query increase by 1
// all array euler[1000000],level[1000000],f_occ[1000000]  are 0 based index
//  seg tree is 1 based index .....

#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
int euler[1000000],level[1000000],f_occ[1000000];
int id=0;
list<int > li[1000000];
int kk=0;
lli dist[1000000];
#define inf 100000000
struct st
 {
  int val;
  int index;
 }  tree[1000000];
 

 
 void dfs(int start,int lev,int par)
  {
    euler[id]=start; 
    level[id]=lev;
    f_occ[start]=min(f_occ[start],id);
    id++;
    
   list<int>:: iterator it;
   for(it=li[start].begin();it!=li[start].end();it++)
    {
      if(*it!=par)
       {
    dfs(*it,lev+1,start);
    euler[id]=start; 
    level[id]=lev;
    f_occ[start]=min(f_occ[start],id);
    id++;
    }
    }
   
  }

st query(int node,int start,int end,int r1,int r2)
 {
 if(start>end || r1>end || r2<start) 
 {
     st ab;
  ab.val=inf;
  ab.index=-1; 
  return ab;
 }
   if(r1<=start && r2>=end)
    {
     return tree[node];
    }
    else
    {
     st q1=query(2*node,start,(start+end)/2,r1,r2);
     st q2=query(2*node+1,((start+end)/2)+1,end,r1,r2);
     if(q1.val<q2.val) return q1;
     else return q2;
    }
 }

void build(int node , int start,int end)
 {
  
  if(start==end) 
  {
   tree[node].val=level[start];
   tree[node].index=start;
   return ;
  }
  else if(start>end)
  {
    tree[node].val=inf;
    tree[node].index=-1;
    return ;
   }
  else
   {
    build(2*node,start,(start+end)/2);
    build(2*node+1,((start+end)/2)+1,end);
    if(tree[2*node].val<tree[2*node+1].val)
    {
     tree[node].val=tree[2*node].val;
     tree[node].index=tree[2*node].index;
 }
 else
 {
   tree[node].val=tree[2*node+1].val;
     tree[node].index=tree[2*node+1].index;
 }
    
   }
 }
  
  int main()
   {
   
    int t;
     cin>>t;
     int cc=0;
     while(t--)
     {
      
       cout<<"Case "<<++cc<<":"<<endl;
  
     int n;
      cin>>n;
       id=0;
      for(int i=1;i<=n;i++)
       {
          li[i].clear();
          int k;
           cin>>k;
           for(int j=0;j<k;j++)
            {
             int x;
              cin>>x;
              li[i].push_back(x);
              li[x].push_back(i);
   }
    }
    
   for(int i=0;i<=2*n;i++) f_occ[i]=1000000;
    dfs(1,1,0);
    id--;
    build(1,0,id);
    int q;
    cin>>q;
    while(q--)
     {
        int a,b;
         cin>>a>>b;
          int x1=f_occ[a];
          int x2=f_occ[b];
          if(x1>x2) swap(x1,x2);
     st lc=query(1,0,id,x1,x2);
     int lca=euler[lc.index];
     cout<<lca<<endl; 

    }
   }
}

---------------------------------------------binary rais solution------------------------------------
// tree is treated as 1 based 
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
list<int>li[1010];
lli dp[1010][30];
int lev[1010];
int dfs(int start,int par,int le)
{
 lev[start]=le;
 list<int>:: iterator it;
 for(it=li[start].begin();it!=li[start].end();it++)
  {
    if(*it!=par)
     {
       dp[*it][0]=start;
       lev[*it]=le+1;
       dfs(*it,start,le+1);
}
  }
}
int binary_rais(int a,int b)// return lca of a,b
 {
 
    // cout<<" find par of "<<a<<"level a  "<<lev[a]<<b<<" lev b "<<lev[b]<<endl;
   if(lev[a]<lev[b]) swap(a,b);
   int lg;
   
   /// maximum jump that can be alloweable to make both a and 
   // b at same level
   for(lg=1;(1<<lg)<=lev[a];lg++);
   
   lg--;
   
   // this will make both at same level
     for(int i=lg;i>=0;i--)
    {
     if(lev[a]-(1<<i)>=lev[b])
         {
        a=dp[a][i];
}
   }
   
   
    // cout<<" at same level "<<a<<" "<<b<<endl;
  if(a==b) return a;
  
  else
  {
   for(int i=lg;i>=0;i--)
   {
   if(dp[a][i]!=-1 && dp[a][i]!=dp[b][i])
    {
      a=dp[a][i];
      b=dp[b][i];
   }
  }
  return dp[a][0];
  }
 }
int main()
{
int t;
 cin>>t;
 int cas=1;
 while(t--)
 {
   cout<<"Case "<<cas++<<":"<<endl;
   for(int i=0;i<1010;i++)li[i].clear();
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
 int k; cin>>k;
 for(int j=0;j<k;j++)
  {
   int a;
    cin>>a;
    li[i].push_back(a);
      } 
}
memset(dp,-1,sizeof dp);
dp[1][0]=0;
dfs(1,-1,1);
    int max_h=20;
    //  maximum height 
    for(int i=1;i<=max_h;i++)
     {
       for(int j=1;j<=n;j++)
        {
            if(dp[j][i-1]!=-1)
    dp[j][i]=dp[dp[j][i-1]][i-1];//
   }
 }
 
 int q;
 cin>>q;
 while(q--)
  {
    int a,b;
     cin>>a>>b;
     cout<< binary_rais(a,b)<<endl;
  }
}
}

Wednesday, 2 March 2016

LCA CODE (MY code both binary rais and segtree )

//  node of the tree is 1 based index so if in any problem nodes are
// 0 based than make it 1 based by increasein 1 each node while
// makin graph , also at  the time of query increase by 1
// all array euler[1000000],level[1000000],f_occ[1000000]  are 0 based index
//  seg tree is 1 based index .....

#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
int euler[1000000],level[1000000],f_occ[1000000];
int id=0;
list<int > li[1000000];
int kk=0;
lli dist[1000000];
#define inf 100000000
struct st
 {
  int val;
  int index;
 }  tree[1000000];



 void dfs(int start,int lev,int par)
  {
    euler[id]=start;
    level[id]=lev;
    f_occ[start]=min(f_occ[start],id);
    id++;
 
   list<int>:: iterator it;
   for(it=li[start].begin();it!=li[start].end();it++)
    {
      if(*it!=par)
       {
    dfs(*it,lev+1,start);
    euler[id]=start;
    level[id]=lev;
    f_occ[start]=min(f_occ[start],id);
    id++;
    }
    }
 
  }

st query(int node,int start,int end,int r1,int r2)
 {
 if(start>end || r1>end || r2<start)
 {
     st ab;
  ab.val=inf;
  ab.index=-1;
  return ab;
 }
   if(r1<=start && r2>=end)
    {
     return tree[node];
    }
    else
    {
     st q1=query(2*node,start,(start+end)/2,r1,r2);
     st q2=query(2*node+1,((start+end)/2)+1,end,r1,r2);
     if(q1.val<q2.val) return q1;
     else return q2;
    }
 }

void build(int node , int start,int end)
 {

  if(start==end)
  {
   tree[node].val=level[start];
   tree[node].index=start;
   return ;
  }
  else if(start>end)
  {
    tree[node].val=inf;
    tree[node].index=-1;
    return ;
   }
  else
   {
    build(2*node,start,(start+end)/2);
    build(2*node+1,((start+end)/2)+1,end);
    if(tree[2*node].val<tree[2*node+1].val)
    {
     tree[node].val=tree[2*node].val;
     tree[node].index=tree[2*node].index;
 }
 else
 {
   tree[node].val=tree[2*node+1].val;
     tree[node].index=tree[2*node+1].index;
 }
 
   }
 }

  int main()
   {
     int n;
      cin>>n;
      for(int i=0;i<n-1;i++)
       {
         int a,b,c;
          cin>>a>>b;
          li[a].push_back(b);
          li[b].push_back(a);
    }
 
   for(int i=0;i<=2*n;i++) f_occ[i]=1000000;
    dfs(1,1,0);
    id--;
    build(1,0,id);
    int q;
    cin>>q;
    while(q--)
     {
        int a,b;
         cin>>a>>b;
          int x1=f_occ[a];
          int x2=f_occ[b];
          if(x1>x2) swap(x1,x2);
     st lc=query(1,0,id,x1,x2);
     int lca=euler[lc.index];
     cout<<lca<<endl;    
    }
   }


---------------------------------------------------------binary rais----------------------------------------
// tree is treated as 1 based
// level is also 1 based

#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
list<int>li[1010];
lli dp[1010][30];
int lev[1010];
int dfs(int start,int par,int le)
{

  lev[start]=le;
  list<int>:: iterator it;
  for(it=li[start].begin();it!=li[start].end();it++)
   {
     if(*it!=par)
      {
        dp[*it][0]=start;
        lev[*it]=le+1;
        dfs(*it,start,le+1);
   }
   }
}


int binary_rais(int a,int b)// return lca of a,b
 {
 
   
   if(lev[a]<lev[b]) swap(a,b);
 
   int lg;
 
   /// maximum jump that can be alloweable to make both a and
   // b at same level  will be the depth of the node a
   for(lg=1;(1<<lg)<=lev[a];lg++);
 
   //
   lg--;
 
   // this will make both at same level
   //  we can write any number as the power of 2
   //  so by binary raise we can reach to any node
     for(int i=lg;i>=0;i--)
      {
        if(lev[a]-(1<<i)>=lev[b])
         {
            a=dp[a][i];//   moving a upward
          }
      }
   
    //  now a and b are at same level
     // cout<<" at same level "<<a<<" "<<b<<endl;
   if(a==b) return a;
 
   else
   {
    for(int i=lg;i>=0;i--)
    {
     if(dp[a][i]!=-1 && dp[a][i]!=dp[b][i])//  moving botha and b up
      {
        a=dp[a][i];
        b=dp[b][i];
      }
    }
    return dp[a][0];
   }
 }


int main()
{

 int t;
  cin>>t;
  int cas=1;
  while(t--)
  {
    cout<<"Case "<<cas++<<":"<<endl;
    for(int i=0;i<1010;i++)li[i].clear();
 int n;
 cin>>n;
 int m ;
  cin>>m;// edge
 
 for(int i=1;i<=m;i++)
 {
  int a,b;
   cin>>a>>b;
   li[a].push_back(b);
   li[b].push_back(a);
}

 memset(dp,-1,sizeof dp);
 // we are consedering 1 as the root of all nodes
 // so its parent is non so its pow(2,0) the parent is 0;

 dp[1][0]=0;
 dfs(1,-1,1);

    int max_h=20;//  or lon(n)
    //  maximum height
    for(int i=1;i<=max_h;i++)
     {
       for(int j=1;j<=n;j++)
        {
            if(dp[j][i-1]!=-1)
       dp[j][i]=dp[dp[j][i-1]][i-1];//
     }
  }
 
  int q;
  cin>>q;
  while(q--)
   {
     int a,b;
      cin>>a>>b;
      cout<< binary_rais(a,b)<<endl;
   }
 }

}

**1471. Distance in the Tree( distance b/w any pair of nodes) (both binary rais and segment solution)

1471. Distance in the Tree


A weighted tree is given. You must find the distance between two given nodes.

Input

The first line contains the number of nodes of the tree n (1 ≤ n ≤ 50000). The nodes are numbered from 0 to n – 1. Each of the next n – 1 lines contains three integers uvw, which correspond to an edge with weight w (0 ≤ w ≤ 1000) connecting nodes u and v. The next line contains the number of queries m (1 ≤ m ≤ 75000). In each of the next m lines there are two integers.

Output

For each query, output the distance between the nodes with the given numbers.

Sample

inputoutput
3
1 0 1
2 0 1
3
0 1
0 2
1 2
1
1
2
Problem Author: Dmitry Zhukov
Problem Source: Ural SU and Orel STU Contest. Petrozavodsk Summer Session, August 2006
---------------------------------------------------------EDITORIAL-------------------------------------
THIS IS A VERY EASY PROBLEM IF WE USE LCA APPROACH ,
DISTANCE B/W a and b = distance b/w  a and  lca(a,b)+ distance b/w b ans lca(a,b),

soo we need to first find  lca ,
now how to find distance b/w a and lca(a,b) . 
initially we find distance of all nodes from node 1 (1 is also  root of the rooted tree) now
distance of a and lca(a,b)= distance a from node 1 - distance of lca(a,b) from 1
similarly distance of b and lca(a,b)=distance b from node 1 - distance of lca(a,b) from 1
hence distance b/w a,b= distance of a from 1 + distance of  b  from 1 - 2*distance of lca(a,b) from 1...

-----------------------------------------------------code------------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
int euler[1000000],level[1000000],f_occ[1000000];
int id=0;
list<pair<int,int> > li[1000000];
int kk=0;
lli dist[1000000];
#define inf 100000000
struct st
 {
  int val;
  int index;
 }  tree[1000000];
int dfs_dist(int start,int par)
 {
// cout<<"start "<<start<<endl;
  list<pair<int,int> >:: iterator it;
  for(it=li[start].begin();it!=li[start].end();it++)
   {
     if(it->first!=par)
      {
      dist[it->first]=it->second+dist[start];
      dfs_dist(it->first,start);
 }
  }
 }
 void dfs(int start,int lev,int par)
  {
  //if(kk++==10) exit(0);
          //cout<<" start "<<start<<" "<<par<<endl;
          euler[id]=start; 
level[id]=lev;
f_occ[start]=min(f_occ[start],id);
id++;
 
  list<pair<int,int> >:: iterator it;
  for(it=li[start].begin();it!=li[start].end();it++)
  {
  if(it->first!=par)
   {
   // cout<<" ap "<<it->first<<endl;
      
dfs(it->first,lev+1,start);
euler[id]=start; 
level[id]=lev;
f_occ[start]=min(f_occ[start],id);
id++;
 }
  }
 
  }

st query(int node,int start,int end,int r1,int r2)
 {
 // if(cc++==10) exit(0);
 // cout<<" start "<<start<<" end "<<end<<" range "<<r1<<" "<<r2<<endl;
 if(start>end || r1>end || r2<start) 
 {
  //cout<<" out of range "<<endl;
     st ab;
ab.val=inf;
ab.index=-1;
return ab;
 }
   if(r1<=start && r2>=end)
    {
     return tree[node];
    }
    else
    {
     st q1=query(2*node,start,(start+end)/2,r1,r2);
     st q2=query(2*node+1,((start+end)/2)+1,end,r1,r2);
     if(q1.val<q2.val) return q1;
     else return q2;
    }
 }

void build(int node , int start,int end)
 {
 
  if(start==end) 
  {
  tree[node].val=level[start];
  tree[node].index=start;
  return ;
  }
  else if(start>end)
  {
  tree[node].val=inf;
  tree[node].index=-1;
  return ;
   }
  else
   {
    build(2*node,start,(start+end)/2);
    build(2*node+1,((start+end)/2)+1,end);
    if(tree[2*node].val<tree[2*node+1].val)
    {
    tree[node].val=tree[2*node].val;
    tree[node].index=tree[2*node].index;
}
else
{
tree[node].val=tree[2*node+1].val;
    tree[node].index=tree[2*node+1].index;
}
    
   }
 }
  
  int main()
   {
    int n;
     cin>>n;
     for(int i=0;i<n-1;i++)
      {
      int a,b,c;
      //  for making 1 based index 
       cin>>a>>b>>c;
       a++,b++;
       li[a].push_back(make_pair(b,c));
       li[b].push_back(make_pair(a,c));
  }
  
 // memset(f_occ,1000000,sizeof f_occ);
 for(int i=0;i<=2*n;i++) f_occ[i]=1000000;
  dfs(1,1,0);
  
  dist[1]=0;
  id--;
  dfs_dist(1,0);
  build(1,0,id);
 /* for(int i=0;i<=id;i++) cout<<euler[i]<<" ";
  cout<<endl;
   for(int i=0;i<=id;i++) cout<<level[i]<<" ";
   cout<<endl;
   for(int i=0;i<=id;i++) cout<<f_occ[i]<<" ";
  cout<<endl;*/
   
  int q;
  cin>>q;
  while(q--)
   {
     int a,b;
      cin>>a>>b;
      a++;
      b++;
       int x1=f_occ[a];
       int x2=f_occ[b];
       if(x1>x2) swap(x1,x2);
        //cout<<x1<<" "<<x2<<endl;
st lc=query(1,0,id,x1,x2);
int lca=euler[lc.index];
// cout<<lca<<endl;
// cout<<"dist "<<dist[a]<<" "<<dist[b]<<" "<<dist[lca]<<endl;
cout<<dist[a]+dist[b]-2*dist[lca]<<endl;
        
}
   }


------------------------------------------------binary rais solution--------------
// tree is treated as 1 based 
// level is also 1 based 

#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
list<pair<int,int> >li[50010];
lli dp[50010][30];
int lev[50010];
int dist[50010];
int dfs(int start,int par,int le,int di)
{

  lev[start]=le;
  list<pair<int,int > >:: iterator it;
  for(it=li[start].begin();it!=li[start].end();it++)
   {
     if(it->first!=par)
      {
        dp[it->first][0]=start;
        lev[it->first]=le+1;
        dist[it->first]=di+it->second;
        dfs(it->first,start,le+1,di+it->second);
   }
   }
}


int binary_rais(int a,int b)// return lca of a,b
 {
  
    
   if(lev[a]<lev[b]) swap(a,b);
   
   int lg;
   
   /// maximum jump that can be alloweable to make both a and 
   // b at same level  will be the depth of the node a 
   for(lg=1;(1<<lg)<=lev[a];lg++);
   
   // 
   lg--;
   
   // this will make both at same level
   //  we can write any number as the power of 2 
   //  so by binary raise we can reach to any node 
     for(int i=lg;i>=0;i--)
      {
        if(lev[a]-(1<<i)>=lev[b])
         {
            a=dp[a][i];//   moving a upward
          }
      }
    
    //  now a and b are at same level 
     // cout<<" at same level "<<a<<" "<<b<<endl;
   if(a==b) return a;
   
   else
   {
    for(int i=lg;i>=0;i--)
    {
     if(dp[a][i]!=-1 && dp[a][i]!=dp[b][i])//  moving botha and b up 
      {
        a=dp[a][i];
        b=dp[b][i];
      }
    }
    return dp[a][0];
   }
 }


int main()
{

 int n;
 cin>>n;

  
 for(int i=0;i<n-1;i++)
 {
   int a,b,c;
    cin>>a>>b>>c;
    a++;// making 1 based ;
    b++;
    li[a].push_back({b,c});
    li[b].push_back({a,c});
}

 memset(dp,-1,sizeof dp);
 // we are consedering 1 as the root of all nodes 
 // so its parent is non so its pow(2,0) the parent is 0;


 dist[1]=0;
 dp[1][0]=0;
 dfs(1,-1,1,0);

    int max_h=20;//  or lon(n)
    //  maximum height 
    for(int i=1;i<=max_h;i++)
     {
       for(int j=1;j<=n;j++)
        {
            if(dp[j][i-1]!=-1)
       dp[j][i]=dp[dp[j][i-1]][i-1];//
     }
  }
  
  int q;
  cin>>q;
  while(q--)
   {
     int a,b;
      cin>>a>>b;
      a++;
      b++;
      int par= binary_rais(a,b);
        cout<<dist[a]+dist[b]-2*dist[par]<<endl;;
      
   }
 }

--------------------------------------------------------------------end----------------------------------------------