POJ 3761 Bubble Sort

Bubble Sort
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2842   Accepted: 982

Description

Bubble sort is a simple sorting algorithm. It works by repeatedly stepping through the list to be sorted, comparing each pair of adjacent items and swapping them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm gets its name from the way smaller elements "bubble" to the top of the list. Because it only uses comparisons to operate on elements, it is a comparison sort.
                ­­­­­­­­­­ Wikipedia

Bubble Sort is a very simple sorting algorithm which runs in O(n2) time. Each round, we start from the beginning of the list, compare each adjacent pair of items in turn, swapping the items if necessary. Repeat the pass through the list, until no swaps are done. Assume that after exactly T rounds, the array is already in the ascending order, then we say that T is the number of Bubble Sort Rounds of this array. Below is an example: Let us take an array of numbers "5 1 4 2 8", then we sort the array using Bubble Sort as follow:

First Round:
5 1 4 2 8 ) -> ( 1 5 4 2 8 ), Compares the first two elements, and swaps them.
( 1 5 4 2 8 ) -> ( 1 4 5 2 8 ), Swap since 5 > 4
( 1 4 5 2 8 ) -> ( 1 4 2 5 8 ), Swap since 5 > 2
( 1 4 2 5 8 ) -> ( 1 4 2 5 8 ), since these elements are already in order (8 > 5), algorithm does not swap them.
Second Round:
1 4 2 5 8 ) -> ( 1 4 2 5 8 )
( 1 4 2 5 8 ) -> ( 1 2 4 5 8 ), Swap since 4 > 2
( 1 2 4 5 8 ) -> ( 1 2 4 5 8 )
( 1 2 4 5 8 ) -> ( 1 2 4 5 8 )

After T = 2 rounds, the array is already sorted, hence we say that the number of Bubble Sort Rounds of this array is equal to 2.

ZX learns Bubble Sort in an algorithm class and his teacher leaves him a problem as homework. The teacher gives ZX an array A with N distinct numbers which is already sorted in ascending order and he tells ZX that this array is obtained after exactly K rounds of Bubble sort. The problem is: How many initial arrays there may be from which we can obtain the array A after exactly K rounds of Bubble Sort? The result may be very large, so you only need to output the answer mod 20100713.  

Input

The input may contain several cases.
The first line contains an integer T (T ≤ 100,000), indicating the number of test cases.
Then T lines of test cases follow. For each line, it contains two integers N and K (1 ≤ N ≤ 1,000,000, 0 ≤ K ≤ N - 1) where N is the size of array and K is the number of Bubble Sort Rounds.

Output

For each line, output an integer which is the number of initial arrays mod 20100713.

Sample Input

3
3 0
3 1
3 2

Sample Output

1
3
2

Hint

Suppose the ordered array is {a, b, c} (a < b < c). For the 6 possible initial arrays:
{a, b, c}, {a, c, b}, {b, a, c}, {b, c, a}, {c, a, b}, {c, b, a},
we can get that:
{a, b, c}: already sorted, no bubble sort needed.
{a, c, b}, {b, a, c}, {c, a, b}: we need 1 round of Bubble Sort.
{b, c, a}, {c, b, a}: we need 2 rounds of Bubble Sort.

大意:題意,求含n個不同元素的排列恰好經過k趟冒泡排序變得有序。問原數組有多少種排列情況

思路:我也是參考了別的大牛的博客才懂的,對於我來說,感覺很難推出來

首先,定義一個反序表f(x)表示在數組中位於元素x左面且大於x的個數。那麼,
1,f(x) = 0 (x = 1,2,...,n)是最終有序的狀態
2,f(x) <= n - x;
3,對於每趟冒泡排序,若f(x) != 0,則f(x)--;//反序表,最大反序表數就是經過趟數
比較好求的是經過不超過k趟冒泡的排列數g(k)
易知,k趟冒泡達到有序的充要條件是 max f(x) == k
所以 n - x <= k;即 x >= n -  k時,x可以放在數組的任意位置。
把元素分爲[1,n-k],[n-k+1,n],在n個位置中放好了前n-k個數後,後k個數的方法爲k!
對於前n-k 個數挨個來看,
首先要是f(1) <= k,則1有k+1個位置可放,放好1後,由於1的位置對f(2)無影響,
2同樣有k+1個位置可放...
g(k) = (k+1)^(n-k) * k!
最終結果則爲 g(k) - g(k-1) = k! * [(k + 1)^(n - k) - k^(n - k)]

上代碼:

#include<iostream>
#include<cmath>
#include<cstring>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#define M 20010
using namespace std;
#define ll long long 
#define  inf 0x3f3f3f3f
const int maxn = 1000010;
ll a[maxn];
#define mod 20100713
//給出了100個測試數據,n最大1000000,1000ms,故打表比較快
void solve()//階乘
{
	a[0] = a[1] = 1;
	for (int i = 2; i <= maxn - 10; i++)
		a[i] = a[i - 1] * i%mod;
}
ll multimod(int a, int b)
{
	ll res = 1, tmp = a;
	while (b)
	{
		if (b & 1)
		{
			res *= tmp;
			res %= mod;
		}
		tmp *= tmp;
		tmp %= mod;
		b >>= 1;
	}
	return res;
}
int main()
{
	//freopen("Text.txt", "r", stdin);
	solve();
	int t, n, k;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d%d", &n, &k);
		if (k == 0)
		{
			printf("1\n");
			continue;
		}
		ll ans = a[k];
		ll ans1 = a[k];
		ans *= multimod(k + 1, n - k);
		ans %= mod;
		ans += mod;//防止ans比ans1小
		ans1 *= multimod(k, n - k);
		ans1 %= mod;
		ans = (ans - ans1) % mod;
		printf("%lld\n", ans);
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章