Repository files navigation
问题定义
输入:一个排列P,一个数字n
输出:在排列P之后的第n个排列(或者该排列不存在)
基本算法描述
计算P的中介数m
计算新的排列中介数m'=n+m
计算m'对应的排列P'
细节算法描述
若P的长度为P.n,则
f(i) = count(P[i] > P[0 .. i-1]) * i!
m = ∑ f(i)
m' = m + n
令 i = P'.n-1 .. 0, x = m', s={1,2, ..., P'.n}
c = x / i!
P'[i] = s中第c+1大的数
s = s - P'[i]
x = x % i!
高精度算法描述
令 i = 0 .. P.n-1, fact = 1
if i>0 : fact = fact * i
m = m + count(P[i] > P[0 .. i-1]) * fact
m' = m + n
令 i = 0 .. P'.n-1
Q[i] = m mod (i+1)
m = [m / (i+1)]
令 i = P'.n-1 .. 0, x = m', s={1,2, ..., P'.n} * c = Q[i]
P'[i] = s中第c+1大的数
s = s - P'[i]
算法细节
count(P[i] > P[0 .. i-1]): 可以用树状数组完成 O(log(P.n)) 的计算
s中第c+1大的数: 可以用线段树(树状数组)完成 O(log(P'.n)) 的计算
需要完成高精度计算
高精度+高精度
高精度*低精度
高精度/低精度
高精度-高精度
高精度之间的大小比较
整体算法复杂度
第一步: O(P.n * ( log(2^31, P.n!) + log(P.n)) )
第二步: O(log(2^31, P.n!))
第三步: O(P.n * ( log(2^31, P.n!) + log(P.n) ))
故总体复杂度: O(P.n * log(2^31, P.n!))
由于 ln(P.n!) ≈ P.n ln(P.n) - P.n + ln(2πP.n)/2
故 log(2^31, P.n!) ≈ (P.n ln(P.n) - P.n + ln(2πP.n)/2) / ln(2^31)
≈ P.n ln(P.n) / 21.4875
总体复杂度约为 O(P.n^2 * ln(P.n) / 21.4875)
细节算法描述
若P的长度为P.n,Q为P的置换表示,则
f(i) = count(Q[i] > Q[0 .. i-1]) * i!
m = ∑ f(i)
m' = m + n
令 i = P'.n - 1 .. 0, x = m', s={1,2, ..., P'.n}
c = x / i!
P'[s中第c+1大的数] = i + 1
x = x % i!
s -= s中第c+1大的数
高精度算法描述
令 i = P.n - 1 .. 0, Q为P的置换表示
m = m * (i + 1) + (Q[i] - count(Q[i] > Q[0 .. i-1]))
m' = m + n
令 i = 0 .. P'.n-1
Q[i] = m mod (i+1)
m = [m / (i+1)]
令 i = P'.n - 1 .. 0, s={1,2, ..., P'.n}
c = Q[i]
P'[s中第c+1大的数] = i + 1
s -= s中第c+1大的数
算法细节
count(Q[i] > Q[0 .. i-1]): 可以使用树状数组完成 O(log(Q.n)) 的计算
需要完成高精度计算
高精度+高精度
高精度*低精度
高精度/低精度
高精度-高精度
高精度之间的大小比较
算法复杂度
O(P.n^2 * ln(P.n) / 21.4875)
细节算法描述
若P的长度为P.n,Q为P的置换表示,则
f(P.n - i - 1) = count(Q[i] > Q[0 .. i-1])
m = f(0) * 1) + f(1) * 2 ) * ...
m' = m + n
令 i = P'.n - 1 .. 0, x = m', s={1,2, ..., P'.n}
c = x % (i + 1)
P'[s中第c+1大的数] = i + 1
x = x / (i + 1)
s -= s中第c+1大的数
高精度算法描述
若P的长度为P.n,Q为P的置换表示,则
f(P.n - i - 1) = count(Q[i] > Q[0 .. i-1])
令 i = 1 .. P.n - 1, Q为P的置换表示
m' = m + n
令 i = P'.n - 1 .. 0, s={1,2, ..., P'.n}
c = x % (i + 1)
x = x / (i + 1)
P'[s中第c+1大的数] = i + 1
s -= s中第c+1大的数
算法细节
count(Q[i] > Q[0 .. i-1]): 可以使用树状数组完成 O(log(Q.n)) 的计算
需要完成高精度计算
高精度+高精度
高精度*低精度
高精度/(%)低精度
高精度-高精度
算法复杂度
O(P.n^2 * ln(P.n) / 21.4875)
细节算法描述
若P的长度为P.n,Q为P的置换表示,则 for i in 1...n-1,其中 tmp(0) = 0
tmp(i) = tmp(i-1) + (i & 1) * tmp(i-2)
f(i) = (tmp(i) & 1) * count(Q[i] > Q[0 .. i - 1] + ((tmp(i) + 1) & 1) * count(Q[i] < Q[0 .. i-1])
m = f(1) * 2) + f(2) * 3 ) * ...
m' = m + n
令 i = P'.n - 1 .. 2, x = m'
D[i] = x % (i + 1)
x = x / (i + 1)
令 i = P'.n - 1 .. 1, 其中cur(1)=0
cur(i) = D[i-1] + (i & 1) * D[i-2]
若i为奇数 r(i) = P'从高向低第(D[i] + 1)个空位的位置
若i为偶数 r(i) = P'从低向高第(D[i] + 1)个空位的位置
P'[r(i)] = i + 1
P'[P'中最后一个空位] = 1
算法细节
count(Q[i] > Q[0 .. i-1]), count(Q[i] < Q[0 .. i-1]): 可以使用树状数组完成 O(log(Q.n)) 的计算
寻找P'中任意方向第i个空位: 可以使用两个树状数组完成 O(log(P'.n)) 的计算
需要完成高精度计算
高精度+高精度
高精度*低精度
高精度/(%)低精度
算法复杂度
O(P.n^2 * ln(P.n) / 21.4875)
About
2014年,组合数学,project1
Resources
Stars
Watchers
Forks
You can’t perform that action at this time.