結果
問題 |
No.1496 不思議な数え上げ
|
ユーザー |
|
提出日時 | 2025-04-19 19:02:27 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,005 ms / 3,000 ms |
コード長 | 3,408 bytes |
コンパイル時間 | 550 ms |
コンパイル使用メモリ | 82,768 KB |
実行使用メモリ | 125,440 KB |
最終ジャッジ日時 | 2025-04-19 19:03:06 |
合計ジャッジ時間 | 31,929 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 39 |
ソースコード
## https://yukicoder.me/problems/no/1496 class BinaryIndexTree: """ フェニック木(BinaryIndexTree)の基本的な機能を実装したクラス """ def __init__(self, size): self.size = size self.array = [0] * (size + 1) def add(self, x, a): index = x while index <= self.size: self.array[index] += a index += index & (-index) def sum(self, x): index = x ans = 0 while index > 0: ans += self.array[index] index -= index & (-index) return ans def least_upper_bound(self, value): if self.sum(self.size) < value: return -1 elif value <= 0: return 0 m = 1 while m < self.size: m *= 2 k = 0 k_sum = 0 while m > 0: k0 = k + m if k0 < self.size: if k_sum + self.array[k0] < value: k_sum += self.array[k0] k += m m //= 2 if k < self.size: return k + 1 else: return -1 def main(): N = int(input()) P = list(map(int, input().split())) A = list(map(int, input().split())) cumsum_a_list = [0] * (N + 1) cumsum_a = 0 for i in range(N): cumsum_a += P[i] cumsum_a_list[i + 1] = cumsum_a p_array = [(i + 1, P[i]) for i in range(N)] p_array.sort(key=lambda x: x[1]) bit = BinaryIndexTree(N) answers = [-1] * N for i in range(N): index = p_array[i][0] l_sum = bit.sum(index) if l_sum == 0: low = 1 else: low = bit.least_upper_bound(l_sum) + 1 if bit.sum(bit.size) == l_sum: high = N else: high = bit.least_upper_bound(l_sum + 1) - 1 answer = 0 if (index - low) <= (high - index): for j in range(low, index + 1): low0 = index high0 = high if cumsum_a_list[low0] - cumsum_a_list[j - 1] > A[i]: continue while high0 - low0 > 1: mid = (high0 + low0) // 2 if cumsum_a_list[mid] - cumsum_a_list[j - 1] <= A[i]: low0 = mid else: high0 = mid if cumsum_a_list[high0] - cumsum_a_list[j - 1] <= A[i]: answer += high0 - index + 1 else: answer += low0 - index + 1 else: for j in range(index, high + 1): low0 = low high0 = index if cumsum_a_list[j] - cumsum_a_list[high0 - 1] > A[i]: continue while high0 - low0 > 1: mid = (high0 + low0) // 2 if cumsum_a_list[j] - cumsum_a_list[mid - 1] <= A[i]: high0 = mid else: low0 = mid if cumsum_a_list[j] - cumsum_a_list[low0 - 1] <= A[i]: answer += index - low0 + 1 else: answer += index - high0 + 1 answers[i] = answer bit.add(index, 1) for i in range(N): print(answers[i]) if __name__ == "__main__": main()