POJ3761

Bubble Sort
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1920 Accepted: 625

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.
 

题意:

给定长度一定的排列和一个整数k,求通过冒泡排序法恰好经过k次后排列完成排序的排列的个数。

分析:

利用逆序数的性质:每一个逆序数排列对应一个原排列,所以只要找出满足条件的逆序数的可能性即可,本题中经过冒泡排序法进行排序,所以逆序数在每进行一次排序后会减一;因此,本题可以转化为求最大逆序数为k的问题,也就是在指定长度的排列中找出最大逆序数为k的所有可能性。

例如:

1 2 3 4 5 6

所有排列中1的逆序数有六种(0,1,2,3,4,5,),2的逆序数有五种。。。i的逆序数有n-i+1种,这里假设k=3,则当求最大逆序数为3时,逆序数小于等于3的可以任意放置,所有逆序数排列的可能性为看k+1!(4*3*2*1);

而处理逆序数大于3的数时,必须要求这些数构成的排列的逆序数的最大值为3,所以这些数的逆序数都要求为4(0,1,2,3),这时的可能性为4*4((k+1)^n-(k+1));

不大于k结果为k+1!*(k+1)^n-(k+1);

又必须保证有3的存在,所以减去小于3的,即不大于2 的即可

k+1!*(k+1)^n-(k+1)-k!*(k)^(n-k)=k!(k+1^n-k-k^n-k);

#include<stdio.h>
#define MOD 20100713
__int64 a[1000007];
__int64 multimod(__int64 tem,__int64 n,__int64 m){
	__int64 ans = 1;
    while (n){
    	if(n&1){
	    	ans*=tem;
	    	ans%=m;	
	    }
	    tem*=tem;
	    tem%=m;
	    n >>= 1;
    }
	return ans;	
}
int main(){
	int T;
	__int64 n,k;
	a[0]=1;
	for(int i=1;i<1000007;i++){
		a[i] = i * a[i-1] % MOD ;
	}
	scanf("%d",&T);
	while(T--){
		scanf("%I64d%I64d",&n,&k);
	    printf("%I64d\n",((multimod(k+1,n-k,MOD)-multimod(k,n-k,MOD) + MOD) % MOD *( a[k] % MOD))%MOD);
	}
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值