結果
問題 | No.992 最長増加部分列の数え上げ |
ユーザー |
![]() |
提出日時 | 2024-07-17 23:25:15 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,056 ms / 2,000 ms |
コード長 | 1,766 bytes |
コンパイル時間 | 186 ms |
コンパイル使用メモリ | 82,160 KB |
実行使用メモリ | 271,476 KB |
最終ジャッジ日時 | 2024-07-17 23:25:41 |
合計ジャッジ時間 | 25,834 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 42 |
ソースコード
from bisect import bisect_leftfrom collections import defaultdictdef compress(a: list) -> list:d = {v: i for i, v in enumerate(sorted(set(a)))}return [d[v] for v in a]class FenwickTree:def __init__(self, n):self.data = [0] * (n+10)self.n = (n+10)def add(self, p, x):assert 0 <= p < self.np += 1while p < len(self.data):self.data[p] += xp += p & -pdef sum(self, p):"""区間 [0, p] の和"""assert 0 <= p < self.np += 1s = 0while p > 0:s += self.data[p]p -= p & -preturn sdef rangesum(self, l, r):"""区間 [l, r] の和"""assert 0 <= l <= r < self.ns = self.sum(r)if l > 0:s -= self.sum(l-1)return s# LIS のアルゴリズム# 各要素のランクを返すdef lis_ranks(a: list) -> list:n = len(a)ranks = [0] * n # ranks[i] : A[i] が LIS の何番目かdp = [INF] * nfor i in range(n):ranks[i] = bisect_left(dp, a[i])dp[ranks[i]] = a[i]return ranksMOD = 10 ** 9 + 7INF = 1 << 60N = int(input())A = compress(list(map(int, input().split())))ranks = lis_ranks(A)max_rank = max(ranks)d = defaultdict(list)for i in range(N):d[ranks[i]].append(i)dp = [0] * Nfor p in d[max_rank]:dp[p] = 1for rank in reversed(range(max_rank)):pp = [0] * Ndp, pp = pp, dpft = FenwickTree(N)inds = d[rank+1].copy()for p in reversed(d[rank]):while inds and p < inds[-1]:k = inds[-1]ft.add(A[k], pp[k])inds.pop()dp[p] = ft.rangesum(A[p]+1, N) % MODans = sum(dp) % MODprint(ans)