Thursday, 22 October 2015

All submissions for this problem are available.

Read problems statements in Mandarin Chinese and Russian.

You are given a permutation A of the first N positive integers. You are also given Q queries to perform one-by-one, the i-th is defined by a pair Xi Yi and has the meaning that you swap the Xi-th number in the permutation with the Yi-th one. After performing each query you should output the number of inversions in the obtained permutation, modulo 2.
The inversion is such a pair (ij) that i < j and Ai > Aj.

Input

The first line of input contains two space separated integers N and Q - the size of the permutation and the number of queries.
The second line contains N space separated integers - the permutation A.
Then there are Q lines. The i-th line contains two space separated integers - Xi and Yi, denoting the i-th query.

Output

Output Q lines. Output the number of inversions in the permutation (modulo 2) after performing the first iqueries on the i-th line.

Constraints

  • 1 ≤ N ≤ 1001 ≤ Q ≤ 100 : 14 points.
  • 1 ≤ N ≤ 10001 ≤ Q ≤ 1000 : 23 points.
  • 1 ≤ N ≤ 1051 ≤ Q ≤ 105 : 63 points.
  • 1 ≤ XiYi ≤ N
  • Xi isn't equal to Yi

Example

Input:
5 1
1 2 3 4 5
2 3

Output:
1


The first hint from this question was the modulo 2 part  . This gave a clear understanding that the solution should be trickyand mathematical . The illustration can be done through and example

Suppose we have this array

6 1 2 3 5 2 2 7 6 9 14 30 15 7 .....

Suppose we want to swap the postions 5 and 12  i.e element 5 and  15.

We can make few inferences that elements for elements less than index 5 and greater than 12 we will have no effect on the inversion count as realtive position after the swap remains the same.
Now coming to the elements that lie in between , they can be divided in three categories one that is less than 5  hence less than 15 the other that is greater than 15 and the third the numbers that lie between them both. It is interesting to observe that for elements less than 8 and greater than 15 have no impact on iversion count but only the elements that lie between for example 9 . Now as we can see for every contirbuting element er add an even amount of inversion count. Like for 9, it forms a new inversion with element 15 presently at index 5 and with 8 at index 12. hence we come to this observation that the output is a sequence of ones and zeroes.

Editorialists explanation

Problem link : contest practice
Difficulty : Simple
Pre-requisites : Basic Math
Problem : Maintain the number of inversions in the permutation (modulo 2), while performing swap operations.

Explanation

At first, let's consider some partial solutions.

How to get 14 points

Here you can simulate the whole process. The constraints are designed in such a way that after every swap, you can calculate the number of inversions again by iterating through all the pairs (ij), where i < j and checking that ai > aj. Then you can output the number of inversions after taking it modulo 2.

How to get 37 points

There are faster methods of calculating the number of inversions, for example O(N log N) algorithm using the merge sort. If you have the same idea as in the 14-point solution, but calculate the number of inversions faster, you can haveO(QN log N) solution that will fit in the TL for the second subtask and will bring you additional 23 points.
Please note that all these solutions doesn't use the fact that we're required to output the answer modulo 2. But modulo makes the problem much simpler than without modulo version. Though, the version without modulo part can be solved within the same time and memory bounds (see related links) for the given constraints.

How to get 100 points

If you run your solution at the different own test cases, you will note that no matter which numbers we swap, the parity of the number of inversions will always change. This gives rise for the following solution:
  • Read the permutation and calculate the number of inversions in it. This can be done in any known way, as it's a standard problem. For example, you can use fenwick tree or merge sort. Writer's solution uses fenwick tree. But this is even an overkill here, because you only need the number of inversions modulo 2. You can use the fact that the permutation 1 2 3 ... N has 0 inversions and every swap operation changes the parity of the number of inversions.
  • Then, read Q queries. No matter what pair of numbers we swap, the parity of the number of inversions in the permutation will change. So the answers will have zeroes and ones alternating.
But how to prove that the parity will always change?
Let's call transposition a swap of two adjacent numbers in the permutation, namely, swap of ai and ai+1.
Let's show that a single transposition always change the parity of the number of inversions. It's easy to see that if the pair (i, i+1) makes an inversion, then after the transposition this pair will not make an inversion and vice versa.
Now consider a general case: when you swap AL and AR (L < R). Say, we want to place AR to the L-th place. We needR-L transpositions to do it.
After we do them, we obtain:
1 2 ... AR AL AL+1 ... AN
Here AL stands at the position L+1, so we need R-L-1 extra transpositions to put it to the R-th place. Then, we'll get:
1 2 ... AR AL+1 ... AL AR+1 ... AN
But that is exactly what we wanted to obtain - this new permutation is obtained from the initial one by doing just a single swap. Now, let's calculate the total number of transpositions done: (R-L)+(R-L-1). It's equal to 2(R-L)-1 - this number is always odd. So the number of transpositions done in the swap is always odd, and knowing that every transposition changes the number of inversions we obtain that every swap changes the number of inversions as well.

Related links

  • problem at SPOJ where you can check your inversion-finding logic. It requires you nothing but calculate the number of inversions in the array.
  • version of this problem without the modulo part at SPOJ. There you need to use some cleverer logic about maintaining the number of inversions. Pay attention that the given array there is not a permutation, so the parity of the number of inversions will not necessary change after every swap there.
#include<iostream>
 #include<bits/stdc++.h>
 using namespace std; int bit[200010]; int arr[200010]; int n; int brr[200010]; void update(int idx,int val) { while(idx<=n) { bit[idx]+=1; idx+=idx & (-idx); } } int query(int idx) { int sum=0; while(idx>0) { sum+=bit[idx]; idx-=idx & (-idx); } return sum; } int main() { long long int ans=0; cin>>n; int q; cin>>q; for(int i=0;i<n;i++) { cin>>arr[i]; brr[i]=arr[i]; } /* data compression is used although not necessary*/ sort(brr,brr+n); for(int i=0;i<n;i++) { int sorted=(lower_bound(brr,brr+n,arr[i]))-brr; arr[i]=sorted+1; }/* goes like the range update point query part*/ // query of arr[i]-1 //update arr[i] with +1 for(int i=n-1;i>=0;i--) { ans+=query(arr[i]-1); update(arr[i],1); } //cout<<ans<<endl; ans=ans%2; int a,b; while(q--) { cin>>a>>b; ans=(ans+1)%2; cout<<ans<<endl; } return 0; }

Tuesday, 20 October 2015

You are given a matrix A that consists of N rows and M columns. Every number in the matrix is either zero or one. Calculate the number of such triples (ijh) where for all the pairs (xy), where both x and y belong to [1h] if y >= xA[i+x-1][j+y-1] equals to one. Of course, the square (iji+h-1j+h-1) should be inside of this matrix. In other words, we're asking you to calculate the amount of square submatrices of a given matrix which have ones on and above their main diagonal.

Input

The first line of the input consists of two integers - N and M.

The following N lines describe the matrix. Each line consists of M characters that are either zero or one.

Output

Output should consist of a single integer - the answer to the problem.

Example

Input:
2 3
011
111

Output:
6

Scoring

Subtask 1 (9 points): 1 <= N,M <= 2000, All the numbers in the matrix are equal to one.

Subtask 2 (12 points): 1 <= N,M <= 10. 

Subtask 3 (34 points): 1 <= N,M <= 30. 

Subtask 4 (17 points): 1 <= N,M <= 150. 

Subtask 5 (28 points): 1 <= N,M <= 2000. 




The subproblem can be seen as for any given submatices its (i-1)(k-1) submatrice has to exist and (i-1)(j) has to 
that will signify that we can form a matrix by appending the extra 1 here.  obviously if the element is 0 then there is no question of having a submatrix



code



#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll dp[3000][3000];
char str[3000];
int arr[2010][2010];

int main()
{
int t;

int n;
cin>>n;
int m;
cin>>m;
for(int i=1;i<=n;i++)
{
cin>>str;
for(int j=1;j<=m;j++)
{
 arr[i][j]=(str[j-1]-'0');
}
}
// cout<<"teaken "<<endl;
for(int i=1;i<=m;i++)
 dp[1][i]=arr[1][i];
 
}
for(int j=1;j<=n;j++)
{
  dp[j][1]=arr[j][1];
}
// cout<<"d1 "<<endl;
for(int i=2;i<=n;i++)
{
 for(int j=2;j<=m;j++)
 {
  if(arr[i][j]==1)
    dp[i][j]=1+min(dp[i-1][j-1],dp[i-1][j]);
    else
    dp[i][j]=0;
 }
}
//11cout<<"done "<<endl;
        ll ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
 ans+=dp[i][j];
 }
}
cout<<ans<<endl;
return 0;
}
Inversion count using BIT



Given an array A of N integers, an inversion of the array is defined as any pair of indexes (i,j)such that ij and A[i]A[j].
  
For example, the array a={2,3,1,5,4} has three inversions: (1,3)(2,3)(4,5), for the pairs of entries (2,1)(3,1)(5,4).

Traditionally the problem of counting the inversions in an array is solved by using a modified version of Merge Sort. In this article we are going to explain another approach using Binary Indexed Tree (BIT, also known as Fenwick Tree)The benefit of this method is that once you understand its mechanics, can be easily extended to many other problems.

Prerequisite


This article assume that you have some basic knowledge of Binary Indexed Trees, if not please first refer to this tutorial.

Replacing the values ​​of the array with indexes


Usually when we are implementing a BIT is necessarily to map the original values of the array to a new range with values between [1,N], where N is the size of the array. This is due to the following reasons:

(1) The values in one or more A[i] entry are too high or too low. 
(e.g. 1012 or 1012).

For example imagine that we are given an array of 3 integers:
{1,1012,5}
This means that if we want to construct a frequency table for our BIT data structure, we are going to need at least an array of 1012 elements. Believe me not a good idea...

(2) The values in one or more A[i] entry are negative
Because we are using arrays it's not possible to handle in our BIT frequency of negative values (e.g. we are not able to do freq[12]).

A simple way to deal with this issues is to replace the original values of the target array for indexes that maintain its relative order.  

For example, given the following array:



The first step is to make a copy of the original array A let's call it B. Then we proceed to sort B in non-descending order as follow:


Using binary search over the array B we are going to seek for every element in the array A, and stored the resulting position indexes (1-based) in the new array A.

binary_search(B,9)=4      found at position 4 of the array B
binary_search(B,1)=1      found at position 1 of the array B
binary_search(B,0)=0      found at position 0 of the array B
binary_search(B,5)=3      found at position 3 of the array B
binary_search(B,4)=2      found at position 2 of the array B

The resulting array after increment each position by one is the following:


The following C++ code fragment illustrate the ideas previously explained:

?
1
2
3
4
5
6
7
8
9
for(int i = 0; i < N; ++i)
   B[i] = A[i]; // copy the content of array A to array B
 
sort(B, B + N); // sort array B
 
for(int i = 0; i < N; ++i) {
   int ind = int(lower_bound(B, B + N, A[i]) - B);
   A[i] = ind + 1;
}


Counting inversions with the accumulate frequency 


The idea to count the inversions with BIT is not to complicate, we start iterating our target array in reverse order, at each point we should ask ourselves the following question "How many numbers less than A[i] have already occurred in the array so far?" this number corresponds to the total number of inversions beginning at some given index. For example consider the following array {3,2,1} when we reach the element 3 we already seen two terms that are less than the number 3, which are 2 and 1. This means that the total number of inversions beginning at the term 3 is two. 


Having this ideas in mind let's see how we can applied BIT to answer the previous question:
  1. read(idx) - accumulate frequency from index 1 to idx
  2. update(idx,val) - update the accumulate frequency at point idx and update the tree.
  3. cumulative frequency array - this array represents the cumulative frequencies (e.g. c[3]=f[1]+f[2]+f[3]) , as a note to the reader this array is not used for the BIT, in this article we used as a way of illustrating the inner workings of this data structure.
Step 1: Initially the cumulative frequency table is empty, we start the process with the element 3, the last one in our array.
 

how many numbers less than 3 have we seen so far
x=read(31) = 0
inv_counter=inv_counter+x

update the count of 3's so far 
update(3,+1)
inv_counter=0 

Step 2: The cumulative frequency of value 3 was increased in the previous step, this is why the read(41) count the inversion (4,3).


how many numbers less than 4 have we seen so far
x=read(41)=1
inv_counter=inv_counter+x

update the count of 4's so far 
update(4,+1)
inv_counter=1

Step 3: The term 1 is the lowest in our array, this is why there is no inversions beginning at 1.


how many numbers less than 1 have we seen so far
x=read(11)=0
inv_counter=inv_counter+x

update the count of 1's so far
update(1,+1)
inv_counter=1


Step 4: Theres is only one inversion involving the value 2 and 1.




how many numbers less than 2 have we seen so far
x=read(21)=1
inv_counter=inv_counter+x

update the count of 2's so far 
update(2,+1)
inv_counter=2

Step 5: There are 4 inversions involving the term 5: (5,2)(5,1)(5,4) and (5,3).




how many numbers less than 5 have we seen so far
x=read(51)=4
inv_counter=inv_counter+x

update the count of 5's so far  
update(5,+1)
inv_counter=6 

The total number of inversion in the array is 6.

The overall time complexity of this solution is O(NlogN), the following code corresponds to a complete implementation of the ideas explained in this tutorial:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <algorithm>
#include <cstdio>
#include <cstring>
 
using namespace std;
 
typedef long long llong;
 
const int MAXN = 500020;
llong tree[MAXN], A[MAXN], B[MAXN];
 
llong read(int idx){
 llong sum = 0;
 while (idx > 0){
  sum += tree[idx];
  idx -= (idx & -idx);
 }
 return sum;
}
 
void update(int idx ,llong val){
 while (idx <= MAXN){
  tree[idx] += val;
  idx += (idx & -idx);
 }
}
 
int main(int argc, char *argv[]) {
   int N;
   while(1 == scanf("%d",&N)) {
      if(!N) break;
      memset(tree, 0, sizeof(tree));     
      for(int i = 0; i < N; ++i) {
         scanf("%lld",&A[i]);
         B[i] = A[i];
      }
      sort(B, B + N);
      for(int i = 0; i < N; ++i) {
         int rank = int(lower_bound(B, B + N, A[i]) - B);
         A[i] = rank + 1;
      }
      llong inv_count = 0;
      for(int i = N - 1; i >= 0; --i) {
         llong x = read(A[i] - 1);
         inv_count += x;
         update(A[i], 1);
      }
      printf("%lld\n",inv_count);
   }
   return 0;
}