結果
| 問題 |
No.696 square1001 and Permutation 5
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 12:59:53 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,046 bytes |
| コンパイル時間 | 322 ms |
| コンパイル使用メモリ | 81,760 KB |
| 実行使用メモリ | 269,468 KB |
| 最終ジャッジ日時 | 2025-05-14 13:02:36 |
| 合計ジャッジ時間 | 22,816 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 2 |
| other | TLE * 1 -- * 11 |
ソースコード
import sys
# Fenwick tree (Binary Indexed Tree) implementation
class FenwickTree:
"""Fenwick Tree for prefix sums and point updates."""
def __init__(self, size):
"""Initializes Fenwick Tree of given size."""
# The tree structure uses 1-based indexing internally.
# The array size needs to be 'size + 1' to accommodate index 'size'.
self.tree = [0] * (size + 1)
self.size = size
def update(self, i, delta):
"""Adds delta to the element at index i."""
# The index i must be 1 <= i <= self.size.
# This method updates the value at index i and all necessary ancestors in the tree.
while i <= self.size:
self.tree[i] += delta
# Move to the next index that represents a range covering index i.
# This is done by adding the least significant bit (LSB).
i += i & (-i)
def query(self, i):
"""Computes the prefix sum up to index i (sum of elements from 1 to i)."""
# Handle query for index 0, which should logically return 0.
if i <= 0:
return 0
# Ensure query index does not exceed the tree size.
if i > self.size:
i = self.size
s = 0
# Sum values by traversing up the tree towards the root (index 0 conceptually).
while i > 0:
s += self.tree[i]
# Move to the parent index in the implicit tree structure.
# This is done by subtracting the least significant bit (LSB).
i -= i & (-i)
return s
def solve():
"""Solves the permutation rank problem."""
# Read the size of the permutation N from standard input.
N = int(sys.stdin.readline())
# Handle edge case N=0. Although problem states N>=1, being safe.
if N == 0:
print(1) # Define rank of empty permutation as 1? Standard is usually 1.
return
# Handle edge case N=1 explicitly.
if N == 1:
# Read the permutation line which contains '1'. We don't need the value.
sys.stdin.readline()
# The only permutation (1) has rank 1.
print(1)
return
# Read the permutation p as a list of N integers.
p = list(map(int, sys.stdin.readline().split()))
# Calculate (N-1)! using Python's built-in arbitrary precision integers (BigInt).
# This value is the factorial term needed for the first position (i=1).
# Initialize factorial value to 1 (for 0!)
current_factorial_val = 1
# The loop calculates product of k=1 to N-1, which is (N-1)!
for k in range(1, N):
current_factorial_val *= k
# Initialize Fenwick tree of size N.
# This tree will maintain the counts of available numbers.
# Initially, all numbers from 1 to N are available.
ft = FenwickTree(N)
# Mark each number i from 1 to N as available by setting its count to 1.
for i in range(1, N + 1):
ft.update(i, 1)
# Initialize the total rank (0-based). Use BigInt to avoid overflow.
total_rank = 0
# Iterate through the permutation positions from 1 to N.
# The loop variable 'i' represents the current position index (1-based).
for i in range(1, N + 1):
# Get the value p_i from the input list p. Since p is 0-indexed, use p[i-1].
p_val = p[i-1]
# Calculate k_{i-1}: the count of available numbers strictly less than p_val.
# This is achieved by querying the Fenwick tree for the prefix sum up to p_val - 1.
# The query ft.query(p_val - 1) sums counts of available numbers in {1, 2, ..., p_val - 1}.
count_smaller_available = ft.query(p_val - 1)
# The factorial term for position i is (N-i)!.
# The variable `current_factorial_val` holds this value.
# Add the contribution of this position to the total rank: k_{i-1} * (N-i)!
term = count_smaller_available * current_factorial_val
total_rank += term
# Mark the number p_val as used (no longer available).
# Update its count in Fenwick tree to 0 by applying an update of -1.
ft.update(p_val, -1)
# Update the factorial value for the next position (i+1).
# The factorial needed for step i+1 is (N-(i+1))! = (N-i-1)!.
# This is calculated by dividing the current factorial (N-i)! by (N-i).
# This division is only valid if N-i > 0.
if N - i > 0:
# Use integer division // which works correctly for Python's BigInts.
current_factorial_val //= (N - i)
# If N - i == 0, it means we just processed the last element (i=N).
# The factorial used was (N-N)! = 0! = 1. No further factorial update is needed.
# The `total_rank` calculated represents the count of permutations lexicographically
# smaller than p. This is the 0-based rank.
# The problem asks for the 1-based rank, so add 1.
print(total_rank + 1)
# Execute the main solution function when the script is run.
solve()
qwewe