Python 45 分,我有一个小问题
查看原帖
Python 45 分,我有一个小问题
101694
yummyeaten楼主2022/12/7 14:52

写的链表+二进制拆位+字典启发式合并,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
2022/12/7 14:52
加载中...