結果

問題 No.3094 Stapler
ユーザー titia
提出日時 2025-05-29 08:14:42
言語 PyPy3
(7.3.15)
結果
RE  
(最新)
AC  
(最初)
実行時間 -
コード長 3,621 bytes
コンパイル時間 335 ms
コンパイル使用メモリ 81,664 KB
実行使用メモリ 138,344 KB
最終ジャッジ日時 2025-06-20 03:04:24
合計ジャッジ時間 29,243 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 71 RE * 1
権限があれば一括ダウンロードができます

ソースコード

diff #

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)
0