結果
| 問題 |
No.1270 Range Arrange Query
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 19:35:27 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,840 bytes |
| コンパイル時間 | 220 ms |
| コンパイル使用メモリ | 82,468 KB |
| 実行使用メモリ | 201,592 KB |
| 最終ジャッジ日時 | 2025-06-12 19:35:47 |
| 合計ジャッジ時間 | 11,411 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 1 WA * 3 TLE * 1 -- * 10 |
ソースコード
import sys
import bisect
def main():
sys.setrecursionlimit(1 << 25)
N, Q = map(int, sys.stdin.readline().split())
a = list(map(int, sys.stdin.readline().split()))
# Precompute prefix and suffix inversion counts
prefix_inv = [0] * (N + 1)
for i in range(1, N+1):
cnt = 0
for j in range(i-1, -1, -1):
if a[j] > a[i-1]:
cnt += 1
prefix_inv[i] = prefix_inv[i-1] + cnt
suffix_inv = [0] * (N + 2)
for i in range(N, 0, -1):
cnt = 0
for j in range(i+1, N+1):
if a[j-1] < a[i-1]:
cnt += 1
suffix_inv[i] = suffix_inv[i+1] + cnt
for _ in range(Q):
l, r = map(int, sys.stdin.readline().split())
l -= 1 # converting to 0-based index
r -= 1
# Extract L and R
L = a[:l]
R = a[r+1:]
# Compute inv(L) and inv(R)
inv_L = prefix_inv[l]
inv_R = suffix_inv[r+2] # since suffix_inv is 1-based
# Compute inv(L, R)
sorted_L = sorted(L)
sorted_R = sorted(R)
i = 0
count = 0
for z in sorted_R:
# Find the number of elements in sorted_L > z
pos = bisect.bisect_right(sorted_L, z)
count += len(sorted_L) - pos
# Compute fixed = inv_L + inv_R + count
fixed = inv_L + inv_R + count
k = r - l + 1
# Function to compute contributes(m)
def contributes(m):
# Number of elements in L > m
cnt_L = len(sorted_L) - bisect.bisect_right(sorted_L, m)
# Number of elements in R < m
cnt_R = bisect.bisect_left(sorted_R, m)
return cnt_L + cnt_R
# Find m_opt via ternary search
left = 1
right = N
m_opt = 1
min_contrib = contributes(1)
for _ in range(100):
if left >= right:
break
m1 = left + (right - left) // 3
m2 = right - (right - left) // 3
c1 = contributes(m1)
c2 = contributes(m2)
if c1 < c2:
right = m2
if c1 < min_contrib:
min_contrib = c1
m_opt = m1
else:
left = m1
if c2 < min_contrib:
min_contrib = c2
m_opt = m2
# Check all possible m in a small range around m_opt
for m in range(max(1, m_opt-5), min(N, m_opt+5)+1):
c = contributes(m)
if c < min_contrib:
min_contrib = c
m_opt = m
S = k * min_contrib
total = fixed + S
print(total)
if __name__ == "__main__":
main()
gew1fw