結果
| 問題 |
No.3094 Stapler
|
| コンテスト | |
| ユーザー |
titia
|
| 提出日時 | 2025-05-29 08:14:42 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 482 ms / 2,000 ms |
| コード長 | 3,621 bytes |
| コンパイル時間 | 277 ms |
| コンパイル使用メモリ | 82,172 KB |
| 実行使用メモリ | 138,428 KB |
| 最終ジャッジ日時 | 2025-10-23 22:38:22 |
| 合計ジャッジ時間 | 28,374 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 72 |
ソースコード
import sys
input = sys.stdin.readline
N=int(input())
Q=int(input())
Queries=[list(map(int,input().split())) for i in range(Q)]
seg_el=1<<(N.bit_length()) # Segment treeの台の要素数
seg_height=1+N.bit_length() # Segment treeのたかさ
SEG=[0]*(4*seg_el) # 1-indexedなので、要素数2*seg_el.Segment treeの初期値で初期化
LAZY=[0]*(2*seg_el) # 1-indexedなので、要素数2*seg_el.Segment treeの初期値で初期化
for i in range(N): # Aを対応する箇所へupdate
SEG[(i+seg_el)*2]=0
SEG[(i+seg_el)*2+1]=1
for i in range(seg_el-1,0,-1): # 親の部分もupdate
SEG[i*2]=0
SEG[i*2+1]=SEG[(i*2)*2+1]+SEG[(i*2+1)*2+1]
def indexes(L,R): # 遅延伝搬すべきノードのリストを返す. (つまり, updateやgetvaluesで見るノードより上にあるノードたち)
INDLIST=[]
R-=1
L>>=1
R>>=1
while L!=R:
if L>R:
INDLIST.append(L)
L>>=1
else:
INDLIST.append(R)
R>>=1
while L!=0:
INDLIST.append(L)
L>>=1
return INDLIST
# 最小値とその個数を取るようにすればよい
def updates(l,r,x): # 区間[l,r)を+x更新
L=l+seg_el
R=r+seg_el
L//=(L & (-L))
R//=(R & (-R))
UPIND=indexes(L,R)
for ind in UPIND[::-1]: # 遅延伝搬
if LAZY[ind]!=0:
update_lazy = LAZY[ind]
LAZY[ind<<1]+=update_lazy
LAZY[1+(ind<<1)]+=update_lazy
SEG[(ind<<1)*2]+=update_lazy
SEG[(1+(ind<<1))*2]+=update_lazy
LAZY[ind]=0
while L!=R:
if L > R:
SEG[2*L]+=x
LAZY[L]+=x
L+=1
L//=(L & (-L))
else:
R-=1
SEG[2*R]+=x
LAZY[R]+=x
R//=(R & (-R))
for ind in UPIND:
if SEG[(ind<<1)*2]<SEG[(1+(ind<<1))*2]:
SEG[ind*2]=SEG[(ind<<1)*2]
SEG[ind*2+1]=SEG[(ind<<1)*2+1]
elif SEG[(ind<<1)*2]>SEG[(1+(ind<<1))*2]:
SEG[ind*2]=SEG[(1+(ind<<1))*2]
SEG[ind*2+1]=SEG[(1+(ind<<1))*2+1]
else:
SEG[ind*2]=SEG[(ind<<1)*2]
SEG[ind*2+1]=SEG[(ind<<1)*2+1]+SEG[(1+(ind<<1))*2+1]
def getvalues(l,r): # 区間[l,r)に関する和を調べる
L=l+seg_el
R=r+seg_el
L//=(L & (-L))
R//=(R & (-R))
UPIND=indexes(L,R)
for ind in UPIND[::-1]: # 遅延伝搬
if LAZY[ind]!=0:
update_lazy = LAZY[ind]
LAZY[ind<<1]+=update_lazy
LAZY[1+(ind<<1)]+=update_lazy
SEG[(ind<<1)*2]+=update_lazy
SEG[(1+(ind<<1))*2]+=update_lazy
LAZY[ind]=0
ANS=0
MIN=1<<60
while L!=R:
if L > R:
if SEG[2*L]<MIN:
MIN=SEG[2*L]
ANS=SEG[2*L+1]
elif SEG[2*L]>MIN:
pass
else:
ANS+=SEG[2*L+1]
L+=1
L//=(L & (-L))
else:
R-=1
if SEG[2*R]<MIN:
MIN=SEG[2*R]
ANS=SEG[2*R+1]
elif SEG[2*R]>MIN:
pass
else:
ANS+=SEG[2*R+1]
R//=(R & (-R))
return MIN,ANS
for L in Queries:
if L[0]==3:
MIN,ANS=getvalues(0,N-1)
#print(MIN,ANS)
if MIN==0:
print(ANS+1)
else:
print(1)
elif L[0]==2:
x=L[1]-1
l,r=Queries[x][1:]
updates(l-1,r-1,-1)
else:
l,r=L[1:]
updates(l-1,r-1,1)
titia