結果
問題 | No.992 最長増加部分列の数え上げ |
ユーザー |
![]() |
提出日時 | 2024-01-30 12:21:46 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 712 ms / 2,000 ms |
コード長 | 2,357 bytes |
コンパイル時間 | 356 ms |
コンパイル使用メモリ | 82,304 KB |
実行使用メモリ | 146,592 KB |
最終ジャッジ日時 | 2024-09-28 10:14:01 |
合計ジャッジ時間 | 22,961 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 42 |
ソースコード
from bisect import *from copy import *def compress(lst):B = []D = dict()vals = deepcopy(lst)vals = list(set(vals))vals.sort()for i in range(len(lst)):ind = bisect_left(vals, lst[i])B.append(ind)for i in range(len(B)):D[lst[i]] = B[i]return B, D, valsclass SegmentTree:def __init__(self,n,identity_e,combine_f,):self._n = nself._size = 1while self._size < self._n:self._size <<= 1self._identity_e = identity_eself._combine_f = combine_fself._node = [self._identity_e] * (2 * self._size)def build(self, array):assert len(array) == self._nfor index, value in enumerate(array, start=self._size):self._node[index] = valuefor index in range(self._size - 1, 0, -1):self._node[index] = self._combine_f(self._node[index << 1 | 0],self._node[index << 1 | 1])def update(self, index, value):i = self._size + indexself._node[i] = valuewhile i > 1:i >>= 1self._node[i] = self._combine_f(self._node[i << 1 | 0],self._node[i << 1 | 1])def fold(self, L, R):L += self._sizeR += self._sizevalue_L = self._identity_evalue_R = self._identity_ewhile L < R:if L & 1:value_L = self._combine_f(value_L, self._node[L])L += 1if R & 1:R -= 1value_R = self._combine_f(self._node[R], value_R)L >>= 1R >>= 1return self._combine_f(value_L, value_R)N = int(input())A = list(map(int, input().split())) + [-10**18]A = compress(A)[0]mod = 10 ** 9 + 7def op(t1, t2):m1, v1 = t1m2, v2 = t2if m1 == m2:return m1, (v1 + v2) % modelif m1 > m2:return t1else:return t2T = SegmentTree(N + 1, (0, 0), op)T.update(0, (1, 1))for i in range(N):t = T.fold(0, A[i])now = T.fold(A[i], A[i] + 1)T.update(A[i], op((t[0] + 1, t[1]), now))print(T.fold(0, N + 1)[1] % mod)