第八大奇迹,python,蓝桥杯,线段树,树套树

第八大奇迹,python,蓝桥杯,线段树,树套树_第1张图片

 第八大奇迹,python,蓝桥杯,线段树,树套树_第2张图片

第八大奇迹,python,蓝桥杯,线段树,树套树_第3张图片

第八大奇迹,python,蓝桥杯,线段树,树套树_第4张图片

思路:本质上是动态区间求第k大问题,由于k被固定且很小,所以最朴素的算法是线段树维护区间前八大的值。

提示:蓝桥云课上这道题所有语言限制为1s,py肯定跑不过,去练习系统交。

code:


l,n=map(int,input().split())
c="C"
q="Q"
num=[0 for i in range(l+1)]
tree=[[] for i in range((n<<2)+100)]
def paixu(mid1,mid2):
    l1=len(mid1)
    l2=len(mid2)
    if (l1+l2<8):
        mid=mid1+mid2
        mid.sort()
        return mid[::-1]
    else:
        mid=[]
        i,j,k=0,0,0
        while (i<8 and jmid2[k]):
                mid.append(mid1[j])
                j+=1
                i+=1
            else:
                mid.append(mid2[k])
                k+=1
                i+=1
        while (i<8 and j>1
    mid1=[]
    mid2=[]
    if (a<=mid):
        mid1=query(x<<1,l,mid,a,b)
    if (b>mid):
        mid2=query(x<<1|1,mid+1,r,a,b)
    return paixu(mid1,mid2)

def update(x,l,r,ind,s):
    if (l==r and l==ind):
        tree[x]=[s]
        return
    mid=(l+r)>>1
    if (ind<=mid):
        update(x<<1,l,mid,ind,s)
    if (ind>mid):
        update(x<<1|1,mid+1,r,ind,s)
    pushup(x)

for i in range(n):
    a,b,d=map(str,input().split())
    b=int(b)
    d=int(d)
    if (a==c):
        update(1,1,l,b,d)
    if (a==q):

        mid=query(1,1,l,b,d)
        if (len(mid)==8):
            print(mid[7])
        else:print(0)

 通过情况:

第八大奇迹,python,蓝桥杯,线段树,树套树_第5张图片

但是这种方法毕竟不普适,比方说下次让你处理第16大呢?或者第k大呢,k是变的,这样就只能用树状数组套线段树了,但是python这个语言效率和空间的使用实在是,难崩。

先贴代码:


import bisect


class node1():  #存储询问
    def __init__(self,opt,a,b):
        self.opt=opt
        self.a=a
        self.b=b

"""class node():  #存储节点
    def __init__(self):
        #print(1)
        self.son=[0,0]
        self.v=0
"""

l1,n=map(int,input().split())
ls=[0 for i  in range(100000*40)]
rs=[0 for i in range(100000*40)]
v=[0 for i in range(100000*40)]
root=[0 for i in range(105000)]
q=[]
C="C"
Q="Q"
num=[]
for i in range(n):
    a,b,c=map(str,input().split())
    b=int(b)
    c=int(c)
    q.append(node1(a,b,c))
    if (a==C):
        num.append(c)
num=list(set(num))
num.sort()
num=[0]+num
l2=len(num)-1
"""print(l2)"""
cnt=0
def tr_update(x,l,r,ind,t):
    global cnt
    if (x==0):
        cnt+=1
        x=cnt
    if (l==r):
        v[x]+=t
        """print(tree[x].v,x)"""
        return x
    mid=(r+l)>>1
    if (ind<=mid):
        x1=tr_update(ls[x],l,mid,ind,t)
        ls[x]=x1
    if (ind>mid):
        x2=tr_update(rs[x],mid+1,r,ind,t)
        rs[x]=x2
    v[x]=v[ls[x]] +v[rs[x]]
    """print(v[x],v[rs[x]],v[ls[x]],x)"""
    return x

def update(pos,ind,t):
    i=pos
    while (i<=l1):
        root[i]=tr_update(root[i],1,l2,ind,t)
        """print(root[i])"""
        i+=i&(-i)

def tr_query(l,r,k):
    global lx, ly
    sm=0
    if (l==r):
        for i in ly:
            sm+=v[i]
        for i in lx:
            sm-=v[i]
        if (k<=sm):
            return l
        return 0
    mid=(l+r)>>1
    for i in ly:
        sm+=v[rs[i]]
    for i in lx:
        sm-=v[rs[i]]
    if (sm>=k):
        for i in range(len(ly)):
            ly[i]=rs[ly[i]]
        for i in range(len(lx)):
            lx[i]=rs[lx[i]]
        return tr_query(mid+1,r,k)
    else:
        for i in range(len(ly)):
            ly[i] = ls[ly[i]]
        for i in range(len(lx)):
            lx[i] = ls[lx[i]]
        return tr_query(l, mid, k-sm)



def query(a,b,k):
    global lx,ly
    i=a-1
    while (i>0):
        lx.append(root[i])
        i-=i&(-i)
    i=b
    while (i>0):
        ly.append(root[i])
        i-=i&(-i)
    return tr_query(1,l2,k)
s=[-1 for i in range(l1+10)]

def find(x):
    return bisect.bisect(num,x)-1

for i in q:
    if (i.opt==C):
        if (s[i.a]==-1):

            update(i.a,find(i.b),1)

            s[i.a]=i.b
        else:
            update(i.a,find(s[i.a]),-1)
            update(i.a, find(i.b), 1)
            s[i.a] = i.b
    else:
        lx=[]
        ly=[]
        #print(i.a, i.b)
        mo=query(i.a,i.b,8)

        if (mo!=0):
            print(num[mo])
        else:
            print(0)




我把node类删了,换成了数组,不然光初始化10e5*40的tree数组就得2s,就是这样还是只能过50%。

通过情况:

第八大奇迹,python,蓝桥杯,线段树,树套树_第6张图片

一言难尽,树状数组套线段树多么精美的算法到python这成了fv,还不如维护一个朴素的线段树好用。

不过再精妙的算法也都是用空间去换时间,用空间和时间去换功能,图1是我用cpp写的朴素线段树,图2是树套树,大家可以看下复杂度,和python对比一下哈哈哈。

第八大奇迹,python,蓝桥杯,线段树,树套树_第7张图片

 

第八大奇迹,python,蓝桥杯,线段树,树套树_第8张图片

 

就到这里吧,累了,弄这个弄了一天。 

你可能感兴趣的:(python,蓝桥杯,开发语言)