首页 > 代码库 > codechef Little Elephant and Permutations题解

codechef Little Elephant and Permutations题解

The Little Elephant likes permutations. This time he has a permutation A[1]A[2], ..., A[N] of numbers 12, ...,N.

He calls a permutation A good, if the number of its inversions is equal to the number of its local inversions. The number of inversions is equal to the number of pairs of integers (ij) such that 1 ≤ i < j ≤ N and A[i] > A[j], and the number of local inversions is the number of integers i such that 1 ≤ i < N and A[i] > A[i+1].

The Little Elephant has several such permutations. Help him to find for each permutation whether it is good or not. Print YES for a corresponding test case if it is good and NO otherwise.

Input

The first line of the input contains a single integer T, the number of test cases. T test cases follow. The first line of each test case contains a single integer N, the size of a permutation. The next line contains N space separated integers A[1]A[2], ..., A[N].

Output

For each test case output a single line containing the answer for the corresponding test case. It should beYES if the corresponding permutation is good and NO otherwise.

Constraints

1 ≤ T ≤ 474

1 ≤ N ≤ 100

It is guaranteed that the sequence A[1]A[2], ..., A[N] is a permutation of numbers 12, ..., N.

Example

Input:
4
1
1
2
2 1
3
3 2 1
4
1 3 2 4

Output:
YES
YES
NO
YES

总结一下有以下关系:

全局逆序数 == 起泡排序交换数据的交换次数

本题数据量小,可以使用暴力法计算。

但是这样时间效率是O(N*N),要想降低到O(nlgn)那么就要使用merger sort。

下面一个类中暴力法和merge sort方法都包括了。


#pragma once
#include <stdio.h>
#include <stdlib.h>

class LittleElephantAndPermutations
{
	int localInverse(const int *A, const int n)
	{
		int ans = 0;
		for (int i = 1; i < n; i++)
		{
			if (A[i-1] > A[i]) ans++;
		}
		return ans;
	}

	int globalInverse(const int *A, const int n)
	{
		int ans = 0;
		for (int i = 0; i < n; i++)
		{
			for (int j = i+1; j < n; j++)
			{
				if (A[i] > A[j]) ans++;
			}
		}
		return ans;
	}

	int *mergeArr(int *left, int L, int *right, int R, int &c)
	{
		int *lr = new int[L+R];
		int i = 0, j = 0, k = 0;
		while (i < L && j < R)
		{
			if (left[i] <= right[j])
			{
				lr[k++] = left[i++];
			}
			else
			{
				lr[k++] = right[j++];
				c += L-i;
			}
		}
		while (i < L)
		{
			lr[k++] = left[i++];
		}
		while (j < R)
		{
			lr[k++] = right[j++];
		}
		return lr;
	}

	int biGlobalInverse(int *&A, const int n)
	{
		if (n <= 1) return 0;

		int mid = (n-1) >> 1;//记得n-1
		int *left = new int[n];
		int *right = new int[n];
		int L = 0, R = 0;

		for ( ; L <= mid; L++)
		{
			left[L] = A[L];
		}
		for (int i = mid+1; i < n; i++, R++)
		{
			right[R] = A[i];
		}
		delete [] A;

		int c1 = biGlobalInverse(left, L);
		int c2 = biGlobalInverse(right, R);

		int c = 0;		
		A = mergeArr(left, L, right, R, c);

		delete left;
		delete right;

		return c1+c2+c;
	}

public:
	void run()
	{
		int T = 0, N = 0;
		scanf("%d", &T);
		while (T--)
		{
			scanf("%d", &N);
			int *A = new int[N];

			for (int i = 0; i < N; i++)
			{
				scanf("%d", &A[i]);
			}
			int loc = localInverse(A, N);
			int glo = biGlobalInverse(A, N);
			if (loc == glo) puts("YES");
			else puts("NO");
		}
	}
};

int littleElephantAndPermutations()
{
	LittleElephantAndPermutations le;
	le.run();
	return 0;
}