結果
| 問題 |
No.1604 Swap Sort:ONE
|
| コンテスト | |
| ユーザー |
👑 SPD_9X2
|
| 提出日時 | 2021-04-26 17:01:41 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 61 ms / 2,000 ms |
| コード長 | 1,684 bytes |
| コンパイル時間 | 296 ms |
| コンパイル使用メモリ | 82,424 KB |
| 実行使用メモリ | 76,148 KB |
| 最終ジャッジ日時 | 2024-07-06 07:50:40 |
| 合計ジャッジ時間 | 2,473 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 24 |
ソースコード
"""
(数字,index)
を昇順ソート
可能かどうかを判定する場合、
差が1以下の数字の間に辺を引く。
連結成分間は、大小関係が定義できる
広義単調増加になっていない場合out
そうでない場合可能で、
indexの方の転倒数が答え。
"""
import sys
from sys import stdin
def bitadd(a,w,bit): #aにwを加える
a += 1
x = a
while x <= (len(bit)-1):
bit[x] += w
x += x & (-1 * x)
def bitsum(a,bit): #ind 0~aまでの和を求める
a += 1
ret = 0
x = a
while x > 0:
ret += bit[x]
x -= x & (-1 * x)
return ret
N = int(stdin.readline())
A = list(map(int,stdin.readline().split()))
assert 2 <= N <= 2*(10**5)
assert 1 <= min(A)
assert max(A) <= 10**9
num_ind = [] #数字、indexを入れておく
for i in range(N):
num_ind.append( (A[i] , i) )
num_ind.sort()
#まず、各数字を連結成分で分ける
linknum = 0 #連結成分番号を管理
lkdic = {} #各数字が、どの連結成分に属すかを管理するmap
lkdic[num_ind[0][0]] = 0
for i in range(1,N):
if num_ind[i-1][0] + 1 < num_ind[i][0]:
linknum += 1
lkdic[num_ind[i][0]] = linknum
#直前に出たことがある場合、最後に出たindexが 現在のindex-1でないと不可能
lastind = {}
lastlk = 0
for i in range(N):
lk = lkdic[A[i]] #連結成分番号
if lk < lastlk:
print (-1)
sys.exit()
else:
lastlk = lk
#あとは転倒数を計算
BIT = [0] * (200100)
ans = 0
for i in range(N):
ans += i - bitsum( num_ind[i][1] , BIT )
bitadd( num_ind[i][1] , 1 , BIT)
print (ans)
SPD_9X2