逆求冒泡排序原序列个数
2016-07-29 12:56
405 查看
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的排列;而直接求不太好求,我么转而求N个数中逆数对不超过K的排列,只有对于1-(n-k)中的数才会有可能是的最大逆序对为K,故先排这些数每个数都有K+1种情况,剩下K个数全排,即K!*(k+1)^(N-K);故((K+1)^(n-K)-K^(k-N))k!的结果即为所求;
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的排列;而直接求不太好求,我么转而求N个数中逆数对不超过K的排列,只有对于1-(n-k)中的数才会有可能是的最大逆序对为K,故先排这些数每个数都有K+1种情况,剩下K个数全排,即K!*(k+1)^(N-K);故((K+1)^(n-K)-K^(k-N))k!的结果即为所求;
#include <cstdio> #include <math.h> using namespace std; const int mod=20100713; long long ff[1000090]; long long cal(int a,int b) { long long t=a,ans=1; while(b) { if(b&1) ans=(ans*t)%mod; t=t*t%mod; b>>=1; } return ans; } void f() { ff[0]=1; for(int i=1;i<=1000001;i++) ff[i]=ff[i-1]*i%mod; } int main() { int t; scanf("%d",&t); f(); while(t--) { int n,k; scanf("%d%d",&n,&k); printf("%lld\n",(cal(k+1,n-k)-cal(k,n-k)+mod)*ff[k]%mod); } return 0; }
相关文章推荐
- 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
- 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
- [BZOJ2754] 喵星球上的点名 - AC自动机/后缀数组/后缀自动机/玄学♂暴力
- html5的视频音频放置方法
- FZU 2163 多米诺骨牌(线段树)
- 二分查找
- 博弈学习 2
- Ajax验证用户名和密码
- Ajax实现简易的三级联动
- 题目113 字符串替换
- HDU 5769 (后缀数组)
- Sass (Syntactically Awesome StyleSheets)
- NCReport高级功能
- Cocos2D-x从0到1之在真机运行cocos项目
- 基于HTML5学生实训设计的几款APP
- Oracle分析函数入门
- bootstrap入门步骤
- 煮酒论测试用例评审
- Linux htop命令
- mongodb 常用命令