結果
問題 | No.711 競技レーティング単調増加 |
ユーザー |
|
提出日時 | 2021-06-16 23:45:35 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 444 ms / 2,000 ms |
コード長 | 4,082 bytes |
コンパイル時間 | 388 ms |
コンパイル使用メモリ | 82,476 KB |
実行使用メモリ | 122,352 KB |
最終ジャッジ日時 | 2024-12-31 14:18:27 |
合計ジャッジ時間 | 11,970 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 41 |
ソースコード
import sysinput = lambda : sys.stdin.readline().rstrip()sys.setrecursionlimit(2*10**5+10)write = lambda x: sys.stdout.write(x+"\n")debug = lambda x: sys.stderr.write(x+"\n")writef = lambda x: print("{:.12f}".format(x))### セグメント木(はやい)class SG:def __init__(self, n, v=None):self._n = nself.geta = 0x = 0while (1 << x) < n:x += 1self._log = xself._size = 1 << self._logself._d = [ninf] * (2 * self._size)if v is not None:for i in range(self._n):self._d[self._size + i] = v[i]for i in range(self._size - 1, 0, -1):self._update(i)def _update(self, k):self._d[k] = op(self._d[2 * k], self._d[2 * k + 1])def update(self, p, x):assert 0 <= p < self._nx -= self.getap += self._sizeself._d[p] = xfor i in range(1, self._log + 1):# self._update(p >> i)k = p>>iself._d[k] = op(self._d[2 * k], self._d[2 * k + 1])def get(self, p):# assert 0 <= p < self._nreturn self._d[p + self._size] + self.getadef check(self):return [self.get(p) for p in range(self._n)]def query(self, left, right):# [l,r)の総和assert 0 <= left <= right <= self._nsml = ninfsmr = ninfleft += self._sizeright += self._size# 外側から計算していく(lは小さい側から, rは大きい側から)while left < right:if left & 1:sml = op(sml, self._d[left])left += 1if right & 1:right -= 1smr = op(self._d[right], smr)left >>= 1right >>= 1return op(sml, smr) + self.getadef update_all(self, v):# 全体加算self.geta += vdef query_all(self):return self._d[1] + self.getadef max_right(self, left, f):"""f(op(a[l], a[l + 1], ..., a[r - 1])) = true となる最大の r-> rはf(op(a[l:r+1]))がFalseになる最小のr"""# assert 0 <= left <= self._n# assert f(ninf)if left == self._n:return self._nleft += self._sizesm = ninffirst = Truewhile first or (left & -left) != left:first = Falsewhile left % 2 == 0:left >>= 1if not f(op(sm, self._d[left])):while left < self._size:left *= 2if f(op(sm, self._d[left])):sm = op(sm, self._d[left])left += 1return left - self._sizesm = op(sm, self._d[left])left += 1return self._ndef min_left(self, right, f):"""f(op(a[l], a[l + 1], ..., a[r - 1])) = true となる最小の l"""# assert 0 <= right <= self._n# assert f(ninf)if right == 0:return 0right += self._sizesm = ninffirst = Truewhile first or (right & -right) != right:first = Falseright -= 1while right > 1 and right % 2:right >>= 1if not f(op(self._d[right], sm)):while right < self._size:right = 2 * right + 1if f(op(self._d[right], sm)):sm = op(self._d[right], sm)right -= 1return right + 1 - self._sizesm = op(self._d[right], sm)return 0op = maxninf = -10**12inf = 10**12n = int(input())a = list(map(int, input().split()))sg = SG(n+1, [ninf]*(n+1))a.insert(0,0)aa = list((a[i]-i for i in range(n+1)))index = list(range(n+1))index.sort(key=lambda i : aa[i])for i in index:if i==0:sg.update(i, 1)else:sg.update(i, sg.query(0,i) + 1)num = sg.query(0, n+1)ans = n + 1 - numprint(ans)