POJ3761 Bubble Sort (组合数学,构造)

2022-10-19,,,

题面

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. ­­­­­­­­­­——­­­­­­­­­­W­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­i­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­k­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­i­­­­­­­­­­­­­­­­­­­­p­­­­­­­­­­­­­­­­­­­­e­­­­­­­­­­­­­­­­­­­­d­­­­­­­­­­­­­­­­­­­­i­­­­­­­­­­­­­­­­­­­­a­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

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 2­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­0­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­1­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­0­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­0­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­7­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­1­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­3.

题解

是一道结论+构造的题。

对于冒泡排序,相信大家都已经很­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­熟­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­悉­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­了­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­。它除了逆序对的性质以外,还有一个性质:每一轮排序,都会使得每个数前面比它大的数个数减少 1,减到 0 不变。

因此,我们可以令

d

i

d_i

di​ 为数字

i

i

i 前面比它大的数个数,那么有

i

,

0

d

i

n

i

\forall i,0\leq d_i\leq n-i

∀i,0≤di​≤n−i 。

为了保证

K

K

K 轮后恰好排完,我们得使

max

d

i

=

K

\max d_i=K

maxdi​=K 。

所以,合法的

d

d

d 序列就有

K

!

(

(

K

+

1

)

n

k

K

n

k

)

K!\cdot((K+1)^{n-k}-K^{n-k})

K!⋅((K+1)n−k−Kn−k) 个。

事实是,这个即为答案,因为我们可以通过一个

d

d

d 序列构造出一个唯一的排列:

从大到小往排列中放入数字。
恒有

d

n

=

0

d_n=0

dn​=0 ,先放入数字

n

n

n ,然后

d

n

1

{

0

,

1

}

d_{n-1}\in\{0,1\}

dn−1​∈{0,1} ,为

0

0

0 就把

n

1

n-1

n−1 紧挨着放

n

n

n 的左边,否则放右边,此时暂时得到一个长为 2 的序列,继续……
我们放数字

i

i

i 时,将

i

i

i 插入到当前已形成的序列第

d

i

d_i

di​ 个位置的后面(为 0 则放最开头),使之满足

d

i

d_i

di​ 的限制。而且,有且仅有这种放法是满足限制的。

最终放完所有数字后,形成一个长度为

n

n

n 的排列,就是一种方案。

综上,答案就是

K

!

(

(

K

+

1

)

n

k

K

n

k

)

K!\cdot((K+1)^{n-k}-K^{n-k})

K!⋅((K+1)n−k−Kn−k) ,预处理阶乘+快速幂 可以达到

O

(

T

log

n

+

n

)

O(T\log n+n)

O(Tlogn+n) 。

CODE

#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1000005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
const ­­­­­­­­­­­­­­­­­­­­int MOD = 20100713;
int n,m,i,j,s,o,k;
int fac[MAXN];
int qkpow(int a,int b) {
int res = 1;
while(b > 0) {
if(b & 1) res = re­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­s *1ll* a % MOD;
a = a *1ll* a % MOD; b >>= 1;
}return res;
}
char ss[MAXN];
int main() {
fac[0] = fac[1] = 1;
for(int i = 2;i <= 100­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­0000;i ++) {
fac[i] = fac[i-1]*1ll*i % MOD;
}
int T = read();
while(T­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ --) {
n = read();k = read();
int ans = (qkpow(k+1,n-k)+MOD-qkpow(k,n-k)) % MOD *1ll* fac[k] % MOD;
printf("%d\n",ans);
}
return 0;
}

POJ3761 Bubble Sort (组合数学,构造)的相关教程结束。

《POJ3761 Bubble Sort (组合数学,构造).doc》

下载本文的Word格式文档,以方便收藏与打印。