結果
| 問題 |
No.2080 Simple Nim Query
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2024-08-18 19:41:04 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,666 ms / 3,000 ms |
| コード長 | 3,964 bytes |
| コンパイル時間 | 260 ms |
| コンパイル使用メモリ | 82,216 KB |
| 実行使用メモリ | 106,052 KB |
| 最終ジャッジ日時 | 2024-08-18 19:41:17 |
| 合計ジャッジ時間 | 11,111 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 8 |
ソースコード
def rec_str(a):return"".join(["[",", ".join(rec_str(x)for x in a),"]"])if isinstance(a,list)else str(a)
class BIT:
def __init__(self,x):
if isinstance(x,int):
self.N=x
self.F=[0]*(x+1)
else:
self.N=len(x)
self.F=[0]*(self.N+1)
for j in R(1,self.N+1):
i=j-1
self.F[j]=x[i]
k=j-(j&-j)
while i>k:
self.F[j]+=self.F[i]
i-=i&-i
def copy(self):
a=__class__([])
a.N=self.N
a.F=self.F[:]
return a
def Add(self,i,u):
i+=1
while i<=self.N:
self.F[i]+=u
i+=i&-i
def Set(self,i,u):self.Add(i,u-self.Get(i))
def Get(self,i):return self.IntervalSum(i,i)
def InitialSegmentSum(self,r):
assert(r>-2)
a=0
i=min(r+1,self.N)
while i:
a+=self.F[i]
i-=i&-i
return a
def IntervalSum(self,l,r):return self.InitialSegmentSum(r)-self.InitialSegmentSum(l-1)
def list(self):return[self.Get(i)for i in R(self.N)]
def __str__(self):return rec_str(self.list())
def Search(self,u):#Computing minimum of j such that InitialSegmentSum(j)>=u or j==N
j=s=n=0
p=1<<17 #131072
while p:
k=j|p
p>>=1
if k<=self.N:
n+=self.F[k]
if n<u:s,j=n,k
else:n=s
return j
class BoundedLineSubset:
def __init__(self,lbound,ubound):
assert(lbound<=ubound+1)
self.lbound=lbound
self.ubound=ubound
self.bit=BIT(ubound-lbound+1)
def copy(self):
a=__class__([])
a.lbound=self.lbound
a.ubound=self.ubound
a.bit=self.bit.copy()
return a
def insert(self,i):assert(self.lbound<=i<=self.ubound);self.bit.Set(i-self.lbound,1)
def erase(self,i):self.bit.Set(i-self.lbound,0)
def count(self,i):return self.bit.Get(i-self.lbound)if self.lbound<=i<=self.ubound else 0
def find(self,i):return self.count(i)>0
def InitialSegmentSize(self,i_final):return self.bit.InitialSegmentSum(i_final-self.lbound)
def IntervalSize(self,i_start,i_final):returnself.bit.IntervalSum(i_start-self.lbound,i_final-self.lbound)
def empty(self):return self.InitialSegmentSize(self.ubound)<1
def MaximumLeq(self,i):#Returning lbound-1 if not exists
num=self.InitialSegmentSize(i)
def f(sum,j):return i<=j or num<=sum
a=self.Search(f)+self.lbound
return a if self.find(a)else self.lbound-1
def MaximumLt(self,i):return self.MaximumLeq(i-1)
def MinimumGeq(self,i):return self.MinimumGt(i-1)
def MinimumGt(self,i):#Returning ubound+1 if not exists
num=self.InitialSegmentSize(i)
def f(sum,j):return i<j and num<sum
return self.Search(f)+self.lbound
def Maximum(self):return self.MaximumLeq(self.ubound)
def Minimum(self):return self.MinimumGeq(self.lbound)
def RightEndPointOf(self,i,b=False):
if not b and not self.find(i):return i-1
d=i-self.lbound
comp=d-self.InitialSegmentSize(i)
def f(sum,j):return d<=j and sum+comp<j
return self.Search(f)+self.lbound-1
def LeftEndPointOf(self,i,b=False):
if not b and not self.find(i):return i+1
d=i-self.lbound
comp=d-self.InitialSegmentSize(i)
def f(sum,j):return d<=j or (self.find(j)and sum+comp==j)
return self.Search(f)+self.lbound
def ConnectedComponentOf(self,i,b=False):
if not b:b=self.find(i)
return[self.LeftEndPointOf(i,b),self.RightEndPointOf(i,b)]
def GetConnectedComponent(self):
a=[]
l=self.Minimum()
while l<=self.ubound:
r=self.RightEndPointOf(l,True)
a+=[[l,r]]
l=self.MinimumGt(r)
return a
def __str__(self):return rec_str(self.GetConnectedComponent())
def lbound(self):return self.lbound
def ubound(self):return self.ubound
#private:
def Search(self,f):#Computing minimum of j satisfying f(InitialSegmentSum(j),j) or j==bit.N
j=s=n=0
p=1<<17 #131072
while p:
k=j|p
p>>=1
if k<=self.bit.N:
n+=self.bit.F[k]
if f(n,k-1):n=s
else:s,j=n,k
return j
R=range
J=lambda:map(int,input().split())
N,Q=J()
A=list(J())
S=BoundedLineSubset(0,N-1)
for i in R(N):
if A[i]==1:S.insert(i)
for _ in R(Q):
T,X,Y=J()
if T==1:
X-=1
S.erase(X)
if Y==1:S.insert(X)
else:
X-=1;Y-=1
l,r=S.ConnectedComponentOf(Y)
print("SF"[r<Y or ((Y-max(X,l))&1)==(X<l)])