結果
問題 | No.921 ずんだアロー |
ユーザー |
|
提出日時 | 2021-03-01 21:26:32 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 217 ms / 2,000 ms |
コード長 | 6,043 bytes |
コンパイル時間 | 241 ms |
コンパイル使用メモリ | 82,408 KB |
実行使用メモリ | 110,948 KB |
最終ジャッジ日時 | 2024-10-03 00:59:10 |
合計ジャッジ時間 | 3,571 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 22 |
ソースコード
"""########## 加算 ############################# chain rule of opdef op(x,y):return x+ye = 0st = SegmentTree(N, op, e)##################################################### 代入 ############################# chain rule of opdef op(x,y):return x if x != e else ye = -float("inf")st = SegmentTree(N, op, e)##################################################### min ############################# chain rule of opdef op(x,y):return x if x < y else ye = -float("inf")st = SegmentTree(N, op, e)##################################################### gcd ############################# chain rule of opdef op(x,y):return gcd(x,y)e = 0st = SegmentTree(N, op, e)##################################################### lcm ############################# chain rule of opdef op(x,y):return a*b//gcd(x,y)e = 1st = SegmentTree(N, op, e)##################################################### 行列積 ############################# chain rule of opdef op(A,B):res = [[0]*len(A) for _ in range(len(A[0]))]for i in range(len(A)):for j in range(len(A[0])):res[i][j] = sum( A[i][k]*B[k][j] for k in range(len(A[0])))return rese = [[1,0],[0,1]]st = SegmentTree(N, op, e)###########################################"""class SegmentTree:def __init__(self, n, op, e):self.n = nself.op = opself.e = eself.size = 1 << (self.n - 1).bit_length() # st[self.size + i] = array[i]self.tree = [self.e] * (self.size << 1)def build(self, array):"""bulid seg tree from array"""for i in range(self.n):self.tree[self.size + i] = array[i]for i in range(self.size - 1, 0, -1):self.tree[i] = self.op(self.tree[i<<1], self.tree[(i<<1)|1])def update(self, i, x):i += self.sizeself.tree[i] = xwhile i > 1:i >>= 1self.tree[i] = self.op(self.tree[i<<1], self.tree[(i<<1)|1])def get_range(self, l, r):"""get value from [l, r) (0-indexed)"""l += self.sizer += self.sizeres_l = self.eres_r = self.ewhile l < r:if l & 1:res_l = self.op(res_l, self.tree[l])l += 1if r & 1:r -= 1res_r = self.op(self.tree[r], res_r)l >>= 1r >>= 1return self.op(res_l, res_r)def max_right(self,l,func):"""return r such that・r = l or f(op(a[l], a[l + 1], ..., a[r - 1])) = true・r = n or f(op(a[l], a[l + 1], ..., a[r])) = false"""if l == self.n: return self.nl += self.sizesm = self.ewhile True:while l % 2 == 0: l >>= 1if not func(self.op(sm,self.tree[l])):while l < self.size:l = 2 * lif func(self.op(sm,self.tree[l])):sm = self.op(sm, self.tree[l])l += 1return l - self.sizesm = self.op(sm, self.tree[l])l += 1if (l & -l) == l: breakreturn self.ndef min_left(self,r,func):"""return l such that・l = r or f(op(a[l], a[l + 1], ..., a[r - 1])) = true・l = 0 or f(op(a[l - 1], a[l], ..., a[r - 1])) = false"""if r == 0: return 0r += self.sizesm = self.ewhile True:r -= 1while r > 1 and (r % 2): r >>= 1if not func(self.op(self.tree[r],sm)):while r < self.size:r = 2 * r + 1if func(self.op(self.tree[r],sm)):sm = self.op(self.tree[r], sm)r -= 1return r + 1 - self.sizesm = self.op(self.tree[r], sm)if (r & -r) == r: breakreturn 0def __getitem__(self, i):if i<0: i=self.n+ireturn self.get_range(i,i+1)def __setitem__(self, i, value):if i<0: i=self.n+iself.update(i,value)def __iter__(self):for a in self.tree[self.size:self.size+self.n]:yield adef __str__(self):return str(self.tree[self.size:self.size+self.n])class CompressSegment:"""data = [(x0,A0),(x1,A1),(x2,A2),...]CS=CompressSegment(data)range: return compressed coordinate[xi,xj) -> [i, j)getitem[i]: return A[xi]i -> A[xi]"""def __init__(self,data):data.sort(key=lambda x:x[0])self.X, self.A, self.Xc = [], [], dict()for i, (x,a) in enumerate(data):self.X.append(x)self.A.append(a)self.Xc[x]=idef __call__(self, l, r):return bisect_left(self.X,l), bisect_left(self.X,r)def range(self, l, r):return bisect_left(self.X,l), bisect_left(self.X,r)def __getitem__(self, i):return self.A[i]def __iter__(self):for a in self.A:yield adef deg(A):"""連続して続く文字を圧縮する(※Counterではない)[1,1,1,2,2,2,3] -> [(1,3),(2,3),(3,1)]"""res=[]a0, cnt=A[0], 1for a in A[1:]+[None]:if a!=a0: res.append((a0,cnt)); cnt=1else: cnt+=1a0=areturn resimport sysfrom bisect import *input = sys.stdin.readlineN=int(input())A=list(map(int, input().split()))data=deg(A)N=len(data)C=[]for a,cnt in data:C.append(cnt)########## max ############################# chain rule of opdef op(x,y):return x if x > y else ye = -float("inf")st = SegmentTree(N, op, e)###########################################st.build(C)for i in range(1,N):a0=st.get_range(0,i-1)if st[i]<=1 and i>=2:st[i]=st[i]+a0else:st[i]=max(st[i]+a0,st[i]-1+st[i-1])print(st.get_range(0,N))