結果
問題 | No.992 最長増加部分列の数え上げ |
ユーザー |
![]() |
提出日時 | 2025-03-31 17:56:03 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 579 ms / 2,000 ms |
コード長 | 3,444 bytes |
コンパイル時間 | 141 ms |
コンパイル使用メモリ | 82,044 KB |
実行使用メモリ | 157,156 KB |
最終ジャッジ日時 | 2025-03-31 17:57:20 |
合計ジャッジ時間 | 19,740 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 42 |
ソースコード
import bisectMOD = 10**9 + 7class SegmentTree:def __init__(self, data_size):self.n = data_sizeself.size = 1while self.size < self.n:self.size <<= 1self.max_len = [0] * (2 * self.size)self.sum_cnt = [0] * (2 * self.size)def update(self, pos, new_len, new_cnt):pos += self.sizeif self.max_len[pos] < new_len:self.max_len[pos] = new_lenself.sum_cnt[pos] = new_cnt % MODelif self.max_len[pos] == new_len:self.sum_cnt[pos] = (self.sum_cnt[pos] + new_cnt) % MODelse:returnpos >>= 1while pos >= 1:left = pos << 1right = left + 1left_max = self.max_len[left]left_cnt = self.sum_cnt[left]right_max = self.max_len[right]right_cnt = self.sum_cnt[right]if left_max > right_max:combined_max = left_maxcombined_cnt = left_cntelif right_max > left_max:combined_max = right_maxcombined_cnt = right_cntelse:combined_max = left_maxcombined_cnt = (left_cnt + right_cnt) % MODif self.max_len[pos] == combined_max and self.sum_cnt[pos] == combined_cnt:breakself.max_len[pos] = combined_maxself.sum_cnt[pos] = combined_cntpos >>= 1def query(self, l, r):res_max = 0res_cnt = 0l += self.sizer += self.sizewhile l <= r:if l % 2 == 1:current_max = self.max_len[l]current_cnt = self.sum_cnt[l]if current_max > res_max:res_max = current_maxres_cnt = current_cntelif current_max == res_max:res_cnt = (res_cnt + current_cnt) % MODl += 1if r % 2 == 0:current_max = self.max_len[r]current_cnt = self.sum_cnt[r]if current_max > res_max:res_max = current_maxres_cnt = current_cntelif current_max == res_max:res_cnt = (res_cnt + current_cnt) % MODr -= 1l >>= 1r >>= 1return res_max, res_cntdef main():import sysinput = sys.stdin.read().split()N = int(input[0])A = list(map(int, input[1:N+1]))sorted_unique = sorted(set(A))m = len(sorted_unique)compressed = []for x in A:k = bisect.bisect_left(sorted_unique, x)compressed.append(k)if m == 0:print(0)returntree = SegmentTree(m)global_max = 0global_sum = 0for k in compressed:if k == 0:max_prev, sum_prev = 0, 0else:max_prev, sum_prev = tree.query(0, k-1)if max_prev == 0 and sum_prev == 0:len_i = 1cnt_i = 1else:len_i = max_prev + 1cnt_i = sum_prevtree.update(k, len_i, cnt_i)if len_i > global_max:global_max = len_iglobal_sum = cnt_ielif len_i == global_max:global_sum = (global_sum + cnt_i) % MODprint(global_sum % MOD)if __name__ == "__main__":main()