結果
| 問題 |
No.1496 不思議な数え上げ
|
| コンテスト | |
| ユーザー |
penguinman
|
| 提出日時 | 2021-04-25 07:33:11 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 977 ms / 3,000 ms |
| コード長 | 3,482 bytes |
| コンパイル時間 | 258 ms |
| コンパイル使用メモリ | 82,792 KB |
| 実行使用メモリ | 122,944 KB |
| 最終ジャッジ日時 | 2024-07-16 03:48:21 |
| 合計ジャッジ時間 | 29,944 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 39 |
ソースコード
# Refernce: https://atcoder.jp/contests/practice2/submissions/16814531
class SegTree():
def __init__(self, a, func, idem):
# the number of nodes is 2n - 1
self.n = 1 << len(a).bit_length()
self.size = len(a)
self.func = func
self.idem = idem # Identity element
self.node = [idem] * (2 * self.n - 1)
for i in range(len(a) + self.n - 2, -1, -1):
if i >= self.n - 1:
self.node[i] = a[i - self.n + 1]
else:
self.node[i] = self.func(self.node[2 * i + 1], self.node[2 * i + 2])
def get(self, x):
return self.node[x + self.n - 1]
def set(self, x, val):
x += self.n - 1
self.node[x] = val
while x > 0:
x = (x - 1) >> 1
self.node[x] = self.func(self.node[2*x+1], self.node[2*x+2])
return
def prod(self, l, r):
L, R = l + self.n, r + self.n
s_l, s_r = self.idem, self.idem
while L < R:
if R & 1:
R -= 1
s_r = self.func(self.node[R-1], s_r)
if L & 1:
s_l = s_l = self.func(s_l, self.node[L-1])
L += 1
L >>= 1
R >>= 1
return self.func(s_l, s_r)
def max_right(self, l, val):
if l == self.size:
return self.size
L = l + self.n
s = self.idem
while 1:
while L % 2 == 0:
L >>= 1
if not val(self.func(s, self.node[L - 1])):
while L < self.n:
L <<= 1
if val(self.func(s, self.node[L-1])):
s = self.func(s, self.node[L-1])
L += 1
return L - self.n
s = self.func(s, self.node[L - 1])
L += 1
if (L & -L) == L:
return self.size
def min_left(self, r, val):
if r == 0:
return 0
R = r + self.n
s = self.idem
while True:
R -= 1
while R > 1 and R % 2:
R >>= 1
if not val(self.func(self.node[R - 1], s)):
while R < self.n:
R = (R << 1) + 1
if val(self.func(self.node[R - 1], s)):
s = self.func(self.node[R - 1], s)
R -= 1
return R + 1 - self.n
s = self.func(self.node[R - 1], s)
if (R & -R) == R:
return 0
import sys
input=sys.stdin.readline
import bisect
inf = int(1e20)
N = int(input())
P = list(map(int, input().split()))
A = list(map(int, input().split()))
rev = [0]*N
dp = [0]*(N+1)
for i in range(N):
dp[i+1] = dp[i]+P[i]
P[i] -= 1
rev[P[i]] = i
seg = SegTree(P, min, inf)
for i in range(N):
ans = 0
left = seg.min_left(rev[i], lambda z: i <= z)
right = seg.max_right(rev[i], lambda z: i <= z)
left = max(left-1, -1)
right = min(right, N)
if rev[i]-left < right-rev[i]:
for l in range(left+1, rev[i]+1):
r = bisect.bisect_right(dp, dp[l]+A[i])
r -= 2
r = max(r, rev[i]-1)
r = min(r, right-1)
ans += r-rev[i]+1
else:
for r in range(rev[i], right):
l = bisect.bisect_left(dp, dp[r+1]-A[i])
l = max(l, left+1)
l = min(l, rev[i]+1)
ans += rev[i]-l+1
print(ans)
penguinman