Re: [algogeeks] Inversion Count

2011-05-13 Thread anshu mishra
no all these data structure also take time O(nlogn)

solving this problem using segment tree

map all elements to its index on the sorted array.

ex. 2 3 8 6 1 -- 1 2 4 3 0

intialiize all element in segment tree wid zero

start from the last index of array

whenever u visit a node increase its value by 1 -- one more value came in
this range

if u have go right child then increase the count by number of element in
left child(that is value left node). thats it;

void query(int a, int s, int e, int node, unsigned long long count)
{
int mid = (s+e)1;
tree[node] += 1;
if (s == e) return;
if (a = mid)
{
query(a, s, mid, (node1)+1, count);
}
else
{
count += tree[(node1)+1];
query(a, mid+1, e, (node1)+2, count);
}
return;
}

I have written another code using ur logic its giving correct answer. I m
not getting where u r wrong. :P

#include stdio.h

unsigned long long int merge_and_count (int *a, int start, int mid, int end)
{
int len_a = mid - start + 1;

int len_b = end - mid;
int C[end - start + 1];
int k = 0;
int i = start;
int j = mid + 1;
unsigned long long int count = 0;
int rem = len_a;

while ( i = mid  j = end ) {

C[k++] = a[i]  a[j] ? a[i] : a[j];
if ( a[j] = a[i] ) {
count += rem;
j++;
} else {
i++;
rem--;
}
}

while ( i = mid ) {
C[k++] = a[i++];
}

while ( j = end ) {

C[k++] = a[j++];
}

for ( i = start; i = end; i++ ) {
a[i] = C[i-start];
}

return count;
}

unsigned long long int sort_and_count(int *a, int start, int end)
{
int mid;

unsigned long long int rA, rB, r;

if ( end == start )
return 0;
else {
mid = (start + end)  1;
rA = sort_and_count (a, start, mid);
rB = sort_and_count (a, mid + 1, end);
r = merge_and_count (a, start, mid, end);

} return (rA+rB+r);
}

int main()
{
int t, n, i;
int a[200100];

scanf (%d, t);

while ( t-- ) {
scanf (%d, n);

for ( i = 0; i  n; i++ ) {

scanf (%d, a[i]);
}

printf (%llu\n, sort_and_count(a, 0, n - 1));
}

return 0;
}

-- 
You received this message because you are subscribed to the Google Groups 
Algorithm Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.



Re: [algogeeks] Inversion Count

2011-05-13 Thread Akshata Sharma
When I replaced cout with printf in my code, I got AC!! I Should have tried
it earlier itself..

On Fri, May 13, 2011 at 11:51 AM, anshu mishra anshumishra6...@gmail.comwrote:

 no all these data structure also take time O(nlogn)

 solving this problem using segment tree

 map all elements to its index on the sorted array.

 ex. 2 3 8 6 1 -- 1 2 4 3 0

 intialiize all element in segment tree wid zero

 start from the last index of array

 whenever u visit a node increase its value by 1 -- one more value came in
 this range

 if u have go right child then increase the count by number of element in
 left child(that is value left node). thats it;

 void query(int a, int s, int e, int node, unsigned long long count)
 {
 int mid = (s+e)1;
 tree[node] += 1;
 if (s == e) return;
 if (a = mid)
 {
 query(a, s, mid, (node1)+1, count);
 }
 else
 {
 count += tree[(node1)+1];
 query(a, mid+1, e, (node1)+2, count);
 }
 return;
 }

 I have written another code using ur logic its giving correct answer. I m
 not getting where u r wrong. :P

 #include stdio.h

 unsigned long long int merge_and_count (int *a, int start, int mid, int
 end)
 {
 int len_a = mid - start + 1;

 int len_b = end - mid;
 int C[end - start + 1];
 int k = 0;
 int i = start;
 int j = mid + 1;
 unsigned long long int count = 0;
 int rem = len_a;

 while ( i = mid  j = end ) {

 C[k++] = a[i]  a[j] ? a[i] : a[j];
 if ( a[j] = a[i] ) {
 count += rem;
 j++;
 } else {
 i++;
 rem--;
 }
 }

 while ( i = mid ) {
 C[k++] = a[i++];
 }

 while ( j = end ) {

 C[k++] = a[j++];
 }

 for ( i = start; i = end; i++ ) {
 a[i] = C[i-start];
 }

 return count;
 }

 unsigned long long int sort_and_count(int *a, int start, int end)
 {
 int mid;

 unsigned long long int rA, rB, r;

 if ( end == start )
 return 0;
 else {
 mid = (start + end)  1;
 rA = sort_and_count (a, start, mid);
 rB = sort_and_count (a, mid + 1, end);
 r = merge_and_count (a, start, mid, end);

 } return (rA+rB+r);
 }

 int main()
 {
 int t, n, i;
 int a[200100];


 scanf (%d, t);

 while ( t-- ) {
 scanf (%d, n);


 for ( i = 0; i  n; i++ ) {

 scanf (%d, a[i]);
 }

 printf (%llu\n, sort_and_count(a, 0, n - 1));
 }

 return 0;

 }


  --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.


-- 
You received this message because you are subscribed to the Google Groups 
Algorithm Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.



Re: [algogeeks] Inversion Count

2011-05-13 Thread topojoy biswas
Cartesian trees could also help.

Cartesian tree takes O(n) time to build, and if you have the count of how
many nodes are  there in a tree rooted at any node, by just having the index
of the element also stored there. Once the cartesian tree is built, just
traverse from the root and find how many nodes are there in the left subtree
from its left child node, and that is the number of inversions for the root
node. Keep doing this for all emenents and kep adding them to a counter.
When you have gone through all the n nodes, you have the total numbr of
inversions, that traversal would also take O(n) time.

When you are at any node, and you know its index in the array, all the
elements to the left sub-tree are inversions because all the elements to the
left of the node are to the left of in the actual array, and that this node
now holds all of the left side of the array rooted at its left child, so all
of them are inversions. And they are the only inversions possible for the
node in questions.


Let me know your views.


Regards
Topo.

On Thu, May 12, 2011 at 5:16 PM, Akshata Sharma
akshatasharm...@gmail.comwrote:

 @Anshu:
 My logic:
 during merge step, lets say you have two array left and right (both are
 sorted) and you are going to merge it.

 l[i] represent the element of left arrray
 r[j] represent the element of right array

 if (r[j]  l[i]) {
   increase the inversion count by the number of elements lefts in left
 array
   put element r[j] into merged array
   j++
 } else {
   no increase in count, just put the element r[i] into merged array
   i++;

 This will be O(nlogn) solution. Can we do better using BIT or segment
 trees? Can you please provide me some hint of how to solve it using segment
 trees, I just know the basics of it..

 On Thu, May 12, 2011 at 5:00 PM, anshu mishra 
 anshumishra6...@gmail.comwrote:

 explain your logic instead of posting code, use binary index tree or
 segment tree or bst to solve this problem.

 --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.


  --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.




-- 
Topo.

There are days when solitude is a heady wine that intoxicates you with
freedom, others when it is a bitter tonic, and still others when it is a
poison that makes you beat your head against the wall.  ~Colette

-- 
You received this message because you are subscribed to the Google Groups 
Algorithm Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.



Re: [algogeeks] Inversion Count

2011-05-13 Thread Terence

Guard value error.

L[n1]=;
R[n2]=999;

R[n2] may be merged and counted, if L[1..n1-1] has 999.


On 2011-5-12 19:18, Akshata Sharma wrote:
I tried to solve this problem using merge sort logic, the algorithm is 
same as merge sort, only change is in the merge step where i am 
counting the inversion_count.
I tested some test cases and I am getting correct answer,  but I am 
getting WA on spoj. Is the code incorrect or any test case whr it fails?


http://www.spoj.pl/problems/INVCNT/


#includeiostream
using namespace std;

long inversion_count = 0;

void merge(long arr[], long p, long q, long r)
{
 long n1 = q-p+1;
 long n2 = r-q;
 long L[n1];
 long R[n2];

 for(long i=0;in1;i++)
 {
  L[i]=arr[p+i];
 }
 L[n1]=;

 for(long i=0;in2;i++)
 {
  R[i]=arr[q+1+i];
 }
 R[n2]=999;
 long i=0;
 long j=0;
 long k=p;

 while(k=r)
 {
  if(L[i]=R[j])
  {
   arr[k]=L[i];
   i++;
   k++;
  }
 else if(L[i]R[j])
 {
  arr[k]=R[j];
  j++;
  k++;
  inversion_count+=n1-i;
 }
}
}

void merge_sort(long arr[], long p, long r)
{
 if(pr)
 {
  long q = (p+r)/2;
  merge_sort(arr,p,q);
  merge_sort(arr,q+1,r);
  merge(arr,p,q,r);
 }
}


int main()
{
 int t;
 char a;
 long n,i;
 long arr[22];
 scanf(%d,t);
 while(t--)
 {
  scanf(%ld,n);
  for(i=0;in;i++)
  scanf(%ld,arr[i]);
  merge_sort(arr,0,n-1);
  coutinversion_count\n;
  inversion_count=0;
 }
return 0;
}

--
You received this message because you are subscribed to the Google 
Groups Algorithm Geeks group.

To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.


--
You received this message because you are subscribed to the Google Groups Algorithm 
Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.



Re: [algogeeks] Inversion Count

2011-05-13 Thread Akshata Sharma
@Terence:
I dont know what a guard value error is, but by mistake I wrote R[n2] =
999, should be one more 9 since array value can be =10^7. May be test
cases have values less than 999 that got me AC.

On Thu, May 12, 2011 at 5:20 PM, Terence technic@gmail.com wrote:

 Guard value error.

 L[n1]=;
 R[n2]=999;

 R[n2] may be merged and counted, if L[1..n1-1] has 999.



 On 2011-5-12 19:18, Akshata Sharma wrote:

 I tried to solve this problem using merge sort logic, the algorithm is
 same as merge sort, only change is in the merge step where i am counting the
 inversion_count.
 I tested some test cases and I am getting correct answer,  but I am
 getting WA on spoj. Is the code incorrect or any test case whr it fails?

 http://www.spoj.pl/problems/INVCNT/


 #includeiostream
 using namespace std;

 long inversion_count = 0;

 void merge(long arr[], long p, long q, long r)
 {
  long n1 = q-p+1;
  long n2 = r-q;
  long L[n1];
  long R[n2];

  for(long i=0;in1;i++)
  {
  L[i]=arr[p+i];
  }
  L[n1]=;

  for(long i=0;in2;i++)
  {
  R[i]=arr[q+1+i];
  }
  R[n2]=999;
  long i=0;
  long j=0;
  long k=p;

  while(k=r)
  {
  if(L[i]=R[j])
  {
   arr[k]=L[i];
   i++;
   k++;
  }
  else if(L[i]R[j])
  {
  arr[k]=R[j];
  j++;
  k++;
  inversion_count+=n1-i;
  }
 }
 }

 void merge_sort(long arr[], long p, long r)
 {
  if(pr)
  {
  long q = (p+r)/2;
  merge_sort(arr,p,q);
  merge_sort(arr,q+1,r);
  merge(arr,p,q,r);
  }
 }


 int main()
 {
  int t;
  char a;
  long n,i;
  long arr[22];
  scanf(%d,t);
  while(t--)
  {
  scanf(%ld,n);
  for(i=0;in;i++)
  scanf(%ld,arr[i]);
  merge_sort(arr,0,n-1);
  coutinversion_count\n;
  inversion_count=0;
  }
 return 0;
 }

 --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.


 --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.



-- 
You received this message because you are subscribed to the Google Groups 
Algorithm Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.



Re: [algogeeks] Inversion Count

2011-05-13 Thread Akshata Sharma
@Topojoy Biswas:

If A = [3, 1, 5, 2, 4] then CT (A) is:

  1
 /  \
3   2
/  \
  54

counting the number of nodes in the tree rooted at each node,

  1(5)
 /\
3(1)  2(3)
  /   \
   5(1)   4(1)

where the numbers in () denotes the number of nodes in tree rooted at that
node.

Once the cartesian tree is built, just traverse from the root and find how
many nodes are there in the left subtree from its left child node, and that
is the number of inversions for the root node

Now, the number of inversions for each node according to you is:
1 - 1
3 - 0
2 - 1
5 - 0
4 - 0

so in total, 2 inversion pairs. But thats not correct. Correct me if I am
wrong.

On Sat, May 14, 2011 at 11:19 AM, Akshata Sharma
akshatasharm...@gmail.comwrote:

 @Terence:
 I dont know what a guard value error is, but by mistake I wrote R[n2] =
 999, should be one more 9 since array value can be =10^7. May be test
 cases have values less than 999 that got me AC.


 On Thu, May 12, 2011 at 5:20 PM, Terence technic@gmail.com wrote:

 Guard value error.

 L[n1]=;
 R[n2]=999;

 R[n2] may be merged and counted, if L[1..n1-1] has 999.



 On 2011-5-12 19:18, Akshata Sharma wrote:

 I tried to solve this problem using merge sort logic, the algorithm is
 same as merge sort, only change is in the merge step where i am counting the
 inversion_count.
 I tested some test cases and I am getting correct answer,  but I am
 getting WA on spoj. Is the code incorrect or any test case whr it fails?

 http://www.spoj.pl/problems/INVCNT/


 #includeiostream
 using namespace std;

 long inversion_count = 0;

 void merge(long arr[], long p, long q, long r)
 {
  long n1 = q-p+1;
  long n2 = r-q;
  long L[n1];
  long R[n2];

  for(long i=0;in1;i++)
  {
  L[i]=arr[p+i];
  }
  L[n1]=;

  for(long i=0;in2;i++)
  {
  R[i]=arr[q+1+i];
  }
  R[n2]=999;
  long i=0;
  long j=0;
  long k=p;

  while(k=r)
  {
  if(L[i]=R[j])
  {
   arr[k]=L[i];
   i++;
   k++;
  }
  else if(L[i]R[j])
  {
  arr[k]=R[j];
  j++;
  k++;
  inversion_count+=n1-i;
  }
 }
 }

 void merge_sort(long arr[], long p, long r)
 {
  if(pr)
  {
  long q = (p+r)/2;
  merge_sort(arr,p,q);
  merge_sort(arr,q+1,r);
  merge(arr,p,q,r);
  }
 }


 int main()
 {
  int t;
  char a;
  long n,i;
  long arr[22];
  scanf(%d,t);
  while(t--)
  {
  scanf(%ld,n);
  for(i=0;in;i++)
  scanf(%ld,arr[i]);
  merge_sort(arr,0,n-1);
  coutinversion_count\n;
  inversion_count=0;
  }
 return 0;
 }

 --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.


 --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.




-- 
You received this message because you are subscribed to the Google Groups 
Algorithm Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.



Re: [algogeeks] Inversion Count

2011-05-12 Thread anshu mishra
explain your logic instead of posting code, use binary index tree or segment
tree or bst to solve this problem.

-- 
You received this message because you are subscribed to the Google Groups 
Algorithm Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.



Re: [algogeeks] Inversion Count

2011-05-12 Thread Akshata Sharma
@Anshu:
My logic:
during merge step, lets say you have two array left and right (both are
sorted) and you are going to merge it.

l[i] represent the element of left arrray
r[j] represent the element of right array

if (r[j]  l[i]) {
  increase the inversion count by the number of elements lefts in left array
  put element r[j] into merged array
  j++
} else {
  no increase in count, just put the element r[i] into merged array
  i++;

This will be O(nlogn) solution. Can we do better using BIT or segment trees?
Can you please provide me some hint of how to solve it using segment trees,
I just know the basics of it..
On Thu, May 12, 2011 at 5:00 PM, anshu mishra anshumishra6...@gmail.comwrote:

 explain your logic instead of posting code, use binary index tree or
 segment tree or bst to solve this problem.

 --
 You received this message because you are subscribed to the Google Groups
 Algorithm Geeks group.
 To post to this group, send email to algogeeks@googlegroups.com.
 To unsubscribe from this group, send email to
 algogeeks+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/algogeeks?hl=en.


-- 
You received this message because you are subscribed to the Google Groups 
Algorithm Geeks group.
To post to this group, send email to algogeeks@googlegroups.com.
To unsubscribe from this group, send email to 
algogeeks+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/algogeeks?hl=en.