提出 #63837482
ソースコード 拡げる
class LazySegTreeFast:
def __init__(self,N,A,op,mapping,composition,e) -> None:
#N:数列の長さ
#A:数列の初期状態
#op:区間で答えたいもの
#mapping:更新方法
#composition:mappingの合成
#e:∀a,op(a,e)=aとなる単位元e
size=1
log_size=1
while size<N:
size*=2
log_size+=1
#size:セグ木の横の大きさ
#log_size:セグ木の深さ
self.size=size
self.log_size=log_size
self.op=op
self.mapping=mapping
self.composition=composition
self.e=e
self.tree=[e]*(2*size)
self.lazy=[None]*(2*size)
#A[i]の長さ
self.long=[0]*(2*size)
#最下層の初期化
for i in range(N):
self.tree[size+i]=A[i]
self.long[size+i]=1
# self.lazy[size+i]=A[i]
#最下層以外の初期化
for i in range((size-1),0,-1):
self.tree[i]=op(self.tree[2*i],self.tree[2*i+1])
self.long[i]=self.long[2*i]+self.long[2*i+1]
#treeの0番目の値は使用しない(欠番)
#seg_treeを深さ順に出力
#時間計算量O(N)
def print_seg_tree(self):
for i in range(self.log_size):
print(self.tree[2**i:2**(i+1)])
#lazyを深さ順に出力
#時間計算量O(N)
def print_lazy(self):
for i in range(self.log_size):
print(self.lazy[2**i:2**(i+1)])
# #Aのi番目(0-indexed)の要素を取得
# #時間計算量O(1)
# def get(self,i):
# return self.tree[self.size+i]
#A[i]のlazyを伝播する
# def lazy_eval(self,i):
# if(self.lazy[i]==None):
# return
# #treeの値を更新する
# self.tree[i]=self.mapping(self.tree[i],self.lazy[i])
# #最下層でない場合
# if(self.size>i):
# self.lazy[2*i]=self.composition(self.lazy[2*i],self.lazy[i])
# self.lazy[2*i+1]=self.composition(self.lazy[2*i+1],self.lazy[i])
# #lazyの値を戻す
# self.lazy[i]=None
#[l,r)から伝播するAのindexを昇順で返す
def root(self,l,r):
L = l + self.size
R = r + self.size
lm = (L // (L & -L)) >> 1
rm = (R // (R & -R)) >> 1
while L < R:
if R <= rm:
yield R
if L <= lm:
yield L
L >>= 1; R >>= 1
while L:
yield L
L >>= 1
def propagates(self,*inds):
for i in reversed(inds):
if(self.lazy[i]==None):
continue
#最下層でない場合
if(self.size>i):
self.lazy[2*i]=self.composition(self.lazy[2*i],self.lazy[i])
self.tree[2*i]=self.mapping(self.tree[2*i],self.lazy[i],self.long[2*i])
self.lazy[2*i+1]=self.composition(self.lazy[2*i+1],self.lazy[i])
self.tree[2*i+1]=self.mapping(self.tree[2*i+1],self.lazy[i],self.long[2*i+1])
self.lazy[i]=None
#Aの[l,r)をmapping(A[i],x)で更新
#時間計算量O(logN)
def update(self,l,r,x):
*inds,=self.root(l,r)
# print(inds,"!")
# self.propagates(*inds)
# self.print_seg_tree()
# self.print_lazy()
# print()
l+=self.size
r+=self.size
while l<r:
# print(l,r)
if(l%2==1):
# print(l,"l")
self.lazy[l]=self.composition(self.lazy[l],x)
self.tree[l]=self.mapping(self.tree[l],x,self.long[l])
l+=1
if(r%2==1):
# print(r,"r")
self.lazy[r-1]=self.composition(self.lazy[r-1],x)
self.tree[r-1]=self.mapping(self.tree[r-1],x,self.long[r-1])
r-=1
l=l//2
r=r//2
# self.print_seg_tree()
# self.print_lazy()
# print()
for i in inds:
self.tree[i]=self.op(self.tree[2*i],self.tree[2*i+1])
if(self.lazy[i]!=None):
self.tree[i]=self.mapping(self.tree[i],self.lazy[i],self.long[i])
#Aの[l,r)に対するop(A[l],op(A[l+1],...op(A[r-1])...))を取得(0-indexed)
def range_op(self,l,r):
*inds,=self.root(l,r)
self.propagates(*inds)
l+=self.size
r+=self.size
left_result=self.e
right_result=self.e
while l<r:
if(l%2==1):
left_result=self.op(left_result,self.tree[l])
l+=1
if(r%2==1):
right_result=self.op(right_result,self.tree[r-1])
r-=1
l=l//2
r=r//2
return self.op(left_result,right_result)
def solve2(N, A):
Lback = [0] * (N - 2)
Lfront = [0] * (N - 2)
S = set([A[-1]])
for i in range(N - 1, 1, -1):
Lback[i - 2] += len(S)
S.add(A[i - 1])
S = set([A[0]])
for i in range(N - 2):
Lfront[i] += len(S)
S.add(A[1 + i])
def LSmap(a,b,l):
return a+b
def LScomp(a,b):
if(a==None):
return b
else:
return a+b
LST = LazySegTreeFast(N, [0] * N, max, LSmap, LScomp, 0)
Last = [-1] * (N + 1)
cnt = 0
ans = 0
for i in range(N - 1):
if(Last[A[i]] == -1):
Last[A[i]] = i
cnt += 1
else:
LST.update(Last[A[i]] + 1, i + 1, 1)
Last[A[i]] = i
if(i >= 1):
#print(Last, cnt, LST.range_op(0, N), Lback[i - 1])
ans = max(ans, cnt + LST.range_op(0, N) + Lback[i - 1])
# else:
# print(Last, cnt, LST.range_op(0, N))
return ans
def gutyoku(N, A):
ans = 0
for i in range(N - 1):
for j in range(i + 1, N - 1):
S = [set() for _ in range(3)]
for x in range(N):
if(x <= i):
S[0].add(A[x])
elif(x <= j):
S[1].add(A[x])
else:
S[2].add(A[x])
ans = max(ans, len(S[0]) + len(S[1]) + len(S[2]))
#print(i, j, ans)
return ans
# import random
# random.seed(51)
# while True:
# N = random.randint(3, 20)
# print(N)
# A = []
# for i in range(N):
# A.append(random.randint(1, N))
# ans1 = solve2(N, A)
# ans2 = gutyoku(N, A)
# if(ans1 != ans2):
# print(N)
# print(*A)
# print(ans1, ans2)
# break
N = int(input())
A = list(map(int, input().split()))
# print(gutyoku(N, A))
print(solve2(N, A))
提出情報
提出日時 |
|
問題 |
F - Variety Split Hard |
ユーザ |
Koi51 |
言語 |
Python (PyPy 3.10-v7.3.12) |
得点 |
550 |
コード長 |
6988 Byte |
結果 |
AC |
実行時間 |
1058 ms |
メモリ |
186020 KiB |
ジャッジ結果
セット名 |
Sample |
All |
得点 / 配点 |
0 / 0 |
550 / 550 |
結果 |
|
|
セット名 |
テストケース |
Sample |
00_sample_00.txt, 00_sample_01.txt |
All |
00_sample_00.txt, 00_sample_01.txt, 01_test_00.txt, 01_test_01.txt, 01_test_02.txt, 01_test_03.txt, 01_test_04.txt, 01_test_05.txt, 01_test_06.txt, 01_test_07.txt, 01_test_08.txt, 01_test_09.txt, 01_test_10.txt, 01_test_11.txt, 01_test_12.txt, 01_test_13.txt, 01_test_14.txt, 01_test_15.txt, 01_test_16.txt, 01_test_17.txt, 01_test_18.txt, 01_test_19.txt, 01_test_20.txt, 01_test_21.txt, 01_test_22.txt, 01_test_23.txt, 01_test_24.txt, 01_test_25.txt, 01_test_26.txt, 01_test_27.txt, 01_test_28.txt, 01_test_29.txt, 01_test_30.txt, 01_test_31.txt, 01_test_32.txt, 01_test_33.txt, 01_test_34.txt, 01_test_35.txt, 01_test_36.txt, 01_test_37.txt, 01_test_38.txt, 01_test_39.txt, 01_test_40.txt, 01_test_41.txt |
ケース名 |
結果 |
実行時間 |
メモリ |
00_sample_00.txt |
AC |
57 ms |
76412 KiB |
00_sample_01.txt |
AC |
57 ms |
76572 KiB |
01_test_00.txt |
AC |
81 ms |
82576 KiB |
01_test_01.txt |
AC |
74 ms |
81680 KiB |
01_test_02.txt |
AC |
91 ms |
83440 KiB |
01_test_03.txt |
AC |
84 ms |
82480 KiB |
01_test_04.txt |
AC |
77 ms |
81928 KiB |
01_test_05.txt |
AC |
304 ms |
116428 KiB |
01_test_06.txt |
AC |
813 ms |
167768 KiB |
01_test_07.txt |
AC |
590 ms |
168312 KiB |
01_test_08.txt |
AC |
870 ms |
167740 KiB |
01_test_09.txt |
AC |
627 ms |
168388 KiB |
01_test_10.txt |
AC |
850 ms |
167848 KiB |
01_test_11.txt |
AC |
334 ms |
123984 KiB |
01_test_12.txt |
AC |
804 ms |
167656 KiB |
01_test_13.txt |
AC |
691 ms |
186020 KiB |
01_test_14.txt |
AC |
839 ms |
168200 KiB |
01_test_15.txt |
AC |
1058 ms |
143888 KiB |
01_test_16.txt |
AC |
544 ms |
143768 KiB |
01_test_17.txt |
AC |
1007 ms |
151084 KiB |
01_test_18.txt |
AC |
506 ms |
151396 KiB |
01_test_19.txt |
AC |
1002 ms |
155232 KiB |
01_test_20.txt |
AC |
517 ms |
155160 KiB |
01_test_21.txt |
AC |
872 ms |
160140 KiB |
01_test_22.txt |
AC |
484 ms |
159988 KiB |
01_test_23.txt |
AC |
805 ms |
164676 KiB |
01_test_24.txt |
AC |
481 ms |
164780 KiB |
01_test_25.txt |
AC |
524 ms |
162644 KiB |
01_test_26.txt |
AC |
540 ms |
164480 KiB |
01_test_27.txt |
AC |
536 ms |
164332 KiB |
01_test_28.txt |
AC |
534 ms |
164780 KiB |
01_test_29.txt |
AC |
528 ms |
163580 KiB |
01_test_30.txt |
AC |
538 ms |
163920 KiB |
01_test_31.txt |
AC |
350 ms |
185216 KiB |
01_test_32.txt |
AC |
382 ms |
185396 KiB |
01_test_33.txt |
AC |
57 ms |
76676 KiB |
01_test_34.txt |
AC |
57 ms |
76296 KiB |
01_test_35.txt |
AC |
444 ms |
167836 KiB |
01_test_36.txt |
AC |
531 ms |
140164 KiB |
01_test_37.txt |
AC |
516 ms |
136472 KiB |
01_test_38.txt |
AC |
355 ms |
185412 KiB |
01_test_39.txt |
AC |
351 ms |
185392 KiB |
01_test_40.txt |
AC |
352 ms |
185224 KiB |
01_test_41.txt |
AC |
354 ms |
185312 KiB |