写的链表+二进制拆位+字典启发式合并,LOJ 50,洛谷 45,剩下全部 TLE。
虽然卡到 100pts 比较困难,但是我想知道复杂度是不是对的?(for i in 字典
的时间复杂度是哈希表大小还是元素个数)
class seq:
def __init__(self,x):
self.val=x
self.lft=None
def append(self,x):
tmp=seq(x)
tmp.lft=self
return tmp
def splice(self,x):
x.lft=self
class mode: # 维护序列中每个二进制位出现次数
def __init__(self):
self.c=[0]*20
def append(self,x):
cur=1
for i in range(20):
if x%(2*cur)>=cur:
self.c[i]+=1
cur*=2
def pop(self,x):
cur=1
for i in range(20):
if x%(2*cur)>=cur:
self.c[i]-=1
cur*=2
def pluseq(self,x): # 将 x 中所有数加到 self 中
for i in range(20):
self.c[i]+=x.c[i]
def best(self,lth): # 计算最有可能成为绝对众数的数
cur,tot=1,0
for i in range(20):
if self.c[i]>lth//2:
tot+=cur
cur*=2
return tot
T=input().split()
n,q=int(T[0]),int(T[1])
heads=[seq(0)]
tails=[seq(0)]
md=[mode()]
sz=[0] # 记录每个序列的长
cnt=[{}] # 记录每个序列中每个数出现的次数
for i in range(1,n+1):
T=input().split()
sz.append(int(T[0]))
md.append(mode())
if T[0]=="0":
heads.append(None)
tails.append(None)
cnt.append({})
continue
heads.append(seq(int(T[1])))
tails.append(heads[-1])
md[-1].append(int(T[1]))
cnt.append({int(T[1]):1})
for j in range(2,len(T)):
V=int(T[j])
tails[-1]=tails[-1].append(V)
md[-1].append(V)
if V in cnt[-1]:
cnt[-1][V]+=1
else:
cnt[-1][V]=1
for i in range(q):
heads.append(None)
tails.append(None)
sz.append(None)
md.append(None)
cnt.append(None)
for Opers in range(q):
T=input().split()
if T[0]=='1':
x,y=int(T[1]),int(T[2])
if tails[x]:
tails[x]=tails[x].append(y)
else:
tails[x]=seq(y)
sz[x]+=1
md[x].append(y)
if y in cnt[x]:
cnt[x][y]+=1
else:
cnt[x][y]=1
if T[0]=='2':
x=int(T[1])
y=tails[x].val
tails[x]=tails[x].lft
sz[x]-=1
md[x].pop(y)
cnt[x][y]-=1
if T[0]=='3':
totmd,totsz=mode(),0
for i in range(2,len(T)):
totmd.pluseq(md[int(T[i])])
totsz+=sz[int(T[i])]
prob=totmd.best(totsz)
cntprob=0
for i in range(2,len(T)):
if prob in cnt[int(T[i])]:
cntprob+=cnt[int(T[i])][prob]
if cntprob>totsz//2:
print(prob)
else:
print(-1)
if T[0]=='4':
x1,x2,x3=int(T[1]),int(T[2]),int(T[3])
if sz[x2]==0:
x1,x2=x2,x1
if sz[x1]==0:
heads[x3],tails[x3],sz[x3],md[x3],cnt[x3]=heads[x2],tails[x2],sz[x2],md[x2],cnt[x2]
continue
tails[x1].splice(heads[x2])
tails[x3]=tails[x2]
heads[x3]=heads[x1]
sz[x3]=sz[x1]+sz[x2]
md[x3]=md[x1]
md[x3].pluseq(md[x2])
if len(cnt[x1])<len(cnt[x2]):
cnt[x3]=cnt[x2]
else:
cnt[x3],cnt[x1]=cnt[x1],cnt[x2]
for num,tms in cnt[x1].items():
if num in cnt[x3]:
cnt[x3][num]+=tms
else:
cnt[x3][num]=tms