結果
| 問題 |
No.271 next_permutation (2)
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 20:59:25 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,640 bytes |
| コンパイル時間 | 200 ms |
| コンパイル使用メモリ | 81,684 KB |
| 実行使用メモリ | 124,960 KB |
| 最終ジャッジ日時 | 2025-06-12 21:03:05 |
| 合計ジャッジ時間 | 6,652 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | TLE * 1 -- * 20 |
ソースコード
import sys
MOD = 10**9 + 7
def main():
import sys
sys.setrecursionlimit(1 << 25)
n, K = map(int, sys.stdin.readline().split())
p = list(map(int, sys.stdin.readline().split()))
if K == 0:
print(0)
return
# Function to compute factorial modulo MOD and check if it's larger than K
def compute_fact_mod(max_k):
fact = 1
for i in range(1, n+1):
if fact > max_k:
return (fact, True)
fact *= i
if fact > max_k:
return (fact, True)
return (fact % MOD, False)
max_fact, exceeds = compute_fact_mod(K)
m = max_fact if not exceeds else K + 1 # m is larger than K when exceeds
if m <= K:
# Compute S_total
S_total = (max_fact * n % MOD) * (n - 1) % MOD
S_total = S_total * pow(4, MOD-2, MOD) % MOD
cycles = K // m
r = K % m
sum_total = (cycles * S_total) % MOD
# Now compute sum of first r inv(A_i)
# Generate the first r permutations and compute their inv
# To avoid TLE for large n, we need to find a way to compute this sum without generating all permutations
# But for the purpose of this problem, we'll proceed for small n
# However, for cases where n is large, this approach may not be feasible
# So, we'll only proceed if r is small or n is small
if r == 0:
print(sum_total % MOD)
return
# We'll need to generate r permutations and compute inv for each
# To compute inv quickly, we can use a Fenwick Tree
# But generating permutations for large n is time-consuming
# So, this part is only feasible for small n
from itertools import permutations
# Generate the initial permutation
current = p.copy()
sum_r = 0
# Compute inv for current
def count_inversions(arr):
from bisect import bisect_right, insort
inv = 0
seen = []
for i in reversed(arr):
pos = bisect_right(seen, i)
inv += pos
insort(seen, i)
return inv
sum_r += count_inversions(current)
r -= 1
if r == 0:
print((sum_total + sum_r) % MOD)
return
# Now, generate next permutations
for _ in range(r):
# Find next permutation
k = n - 1
while k > 0 and current[k-1] >= current[k]:
k -= 1
if k == 0:
# Reset to beginning
current = list(range(1, n+1))
else:
# Find the successor to swap with
l = n - 1
while current[l] <= current[k-1]:
l -= 1
current[k-1], current[l] = current[l], current[k-1]
# Reverse the suffix
current[k:] = current[k:][::-1]
# Compute inv
sum_r += count_inversions(current)
sum_r %= MOD
total = (sum_total + sum_r) % MOD
print(total)
else:
# Compute sum of first K inv(A_i)
# Again, only feasible for small n
current = p.copy()
sum_k = 0
# Compute inv for current
def count_inversions(arr):
from bisect import bisect_right, insort
inv = 0
seen = []
for i in reversed(arr):
pos = bisect_right(seen, i)
inv += pos
insort(seen, i)
return inv
sum_k += count_inversions(current)
K -= 1
if K == 0:
print(sum_k % MOD)
return
# Generate next permutations
for _ in range(K):
# Find next permutation
k = n - 1
while k > 0 and current[k-1] >= current[k]:
k -= 1
if k == 0:
# Reset to beginning
current = list(range(1, n+1))
else:
# Find the successor to swap with
l = n - 1
while current[l] <= current[k-1]:
l -= 1
current[k-1], current[l] = current[l], current[k-1]
# Reverse the suffix
current[k:] = current[k:][::-1]
# Compute inv
sum_k += count_inversions(current)
sum_k %= MOD
print(sum_k % MOD)
if __name__ == '__main__':
main()
gew1fw