Python-多次添加到列表拼接、优化、算法

Python-多次添加到列表拼接、优化、算法,python,algorithm,list,optimization,splice,Python,Algorithm,List,Optimization,Splice,我试图在拼接l[I:j(包括)]中向列表I的每个列表元素添加一个常量num_to_add,在拼接l[I:j(包括)]中,我得到了许多形式为[I,j,num_to_add]的查询 其中t的格式为[[i,j,num_to_add],[i,j,num_to_add]等] 我把t的每个元素加到列表I中,列表I完全由零组成 我目前的代码是: 我循环遍历t、我的查询中的子列表,并将num_添加到每个列表元素中。我输出列表I中小于整数n的元素数 如何从嵌套for循环中优化它?这是一个问题的一小部分,也适用于其

我试图在拼接l[I:j(包括)]中向列表I的每个列表元素添加一个常量num_to_add,在拼接l[I:j(包括)]中,我得到了许多形式为[I,j,num_to_add]的查询

其中t的格式为[[i,j,num_to_add],[i,j,num_to_add]等] 我把t的每个元素加到列表I中,列表I完全由零组成

我目前的代码是: 我循环遍历t、我的查询中的子列表,并将num_添加到每个列表元素中。我输出列表I中小于整数n的元素数

如何从嵌套for循环中优化它?这是一个问题的一小部分,也适用于其他项目

编辑4: 样本输入:

4
1
3
1 3 1
2 3 2
3 3 2
编辑5: 完整代码:

I = [0] * int(input())
n = int(input())
j = int(input())
t = [list(map(int, input().split())) for i in range(j)]

tree = []
for i in range(1, 2*len(I)+1):
    tree.append([0,0])

def update(pos , left , right , i , j , val):

    ####updating segment tree to add value val in list l from index i to j

    i=max(i , left)
    j=min(j , right)
    if i > j:
       return

    if i==left and j==right:
       tree[pos][0] = tree[pos][0] + val*( j - i + 1 )
       tree[pos][1] = tree[pos][1] + val
       return

    mid = (left + right)/2

    ### the range breaks down into two parts left to mid and mid+1 to right 
    ### at positions 2*pos and 2*pos+1 in tree respectively

    update(2*pos , left , mid , i , j , val)
    update(2*pos + 1 , mid+1 , right , i , j , val) 
    tree[pos][0] = tree[2*pos][0] + tree[2*pos + 1][0] + tree[pos][1]*(right - left +1 ) 


def getvalue(pos , left , right , i , j ):

    ###gets sum of elements in list from index i to j in our case
    ### i will be equal to j , will see below 

    i = max(i , left)
    j=  min(j , right)
    if i > j:
        return 0
    if i==left and j==right:
        return tree[pos][0]

    mid = (left + right)/2 
    return getvalue(2*pos , left , mid , i , j) + getvalue(2*pos+1 , mid+1 , right , i , j) + tree[pos][1]*(j - i + 1)

###Remember l is 1 based indexed
for i in range( len(t) ):
    update(1 , 1 , len(I) , t[i][0] , t[i][1] , t[i][2])

ans = 0

###Remember l is 1 based indexed
for i in range(1 , len(I)+1):
   ###see we only use getvalue where i and j parameters of getvalue are same
   value = getvalue(1 , 1 , len(I) , i , i) 
   if value < n:
       ans = ans + 1

print(ans)
I=[0]*int(input())
n=int(输入())
j=int(输入())
t=[范围(j)内i的列表(映射(int,input().split())]
树=[]
对于范围(1,2*len(i)+1)内的i:
tree.append([0,0])
def更新(位置、左、右、i、j、val):
####更新段树以将列表l中的值val从索引i添加到j
i=最大值(i,左)
j=最小值(j,右)
如果i>j:
返回
如果i==左,j==右:
树[pos][0]=树[pos][0]+val*(j-i+1)
树[pos][1]=树[pos][1]+val
返回
中间=(左+右)/2
###该范围分为从左到中和从中到右+1两部分
###分别位于树中的位置2*pos和位置2*pos+1
更新(2*pos、左、中、i、j、val)
更新(2*pos+1,mid+1,right,i,j,val)
树[pos][0]=树[2*pos][0]+树[2*pos+1][0]+树[pos][1]*(右-左+1)
def getvalue(位置、左、右、i、j):
###在本例中,获取从索引i到j的列表中元素的总和
###我将等于j,如下所示
i=最大值(i,左)
j=最小值(j,右)
如果i>j:
返回0
如果i==左,j==右:
返回树[pos][0]
中间=(左+右)/2
返回getvalue(2*pos,left,mid,i,j)+getvalue(2*pos+1,mid+1,right,i,j)+树[pos][1]*(j-i+1)
###记住l是基于1的索引
对于范围内的i(len(t)):
更新(1,1,len(I),t[I][0],t[I][1],t[I][2])
ans=0
###记住l是基于1的索引
对于范围(1,len(i)+1)内的i:
###请看,我们仅在getvalue的i和j参数相同的情况下使用getvalue
value=getvalue(1,1,len(I),I,I)
如果值
错误:

Traceback (most recent call last):
  File, line 58, in <module>
    value = getvalue(1 , 1 , len(I) , i , i)
# A lot of these:
  File "/home/max3/Documents/Python/DMOJ TCE Battle Positions.py", line 47, in getvalue
    return getvalue(2*pos , left , mid , i , j) + getvalue(2*pos+1 , mid+1 , right , i , j) + tree[pos][1]*(j - i + 1)
# And one of this.
  File "/home/max3/Documents/Python/DMOJ TCE Battle Positions.py", line 44, in getvalue
    return tree[pos][0]
IndexError: list index out of range
回溯(最近一次呼叫最后一次):
文件,第58行,在
value=getvalue(1,1,len(I),I,I)
#其中很多:
文件“/home/max3/Documents/Python/DMOJ TCE Battle Positions.py”,第47行,在getvalue中
返回getvalue(2*pos,left,mid,i,j)+getvalue(2*pos+1,mid+1,right,i,j)+树[pos][1]*(j-i+1)
#还有这个。
文件“/home/max3/Documents/Python/DMOJ TCE Battle Positions.py”,第44行,在getvalue中
返回树[pos][0]
索引器:列表索引超出范围

段树使您能够更新和检索O(logN)中列表中的元素总和,其中N是列表的大小。查找并说服自己分段树是如何工作的 .
tree(另一个列表)作为段树,它的大小是列表的两倍l,并且它的每个元素是另一个大小为2的列表,初始化为零。(我将ltree都作为基于1的索引)。这适用于所有i从1到2N的树[i]=[0,0]tree[i][0]是此索引对应的范围和更新时添加到此范围的值之和。eg树[1][0]存储范围为1到N的元素总和

I = [0] * int(input())
n = int(input())
j = int(input())
t=[] 
tree=[]
for i in range(j):
   s=raw_input()
   l=s.split()
   for x in range(len(l)):
       l[x]=int(l[x])
   t.append(l)

for i in range(1,2*len(I)+1):
   tree.append([0,0])

def update(pos , left , right , i , j , val):

    ####updating segment tree to add value val in list l from index i to j

    i=max(i , left)
    j=min(j , right)
    if i > j:
       return

    if i==left and j==right:
       tree[pos][0] = tree[pos][0] + val*( j - i + 1 )
       tree[pos][1] = tree[pos][1] + val
       return

    mid = (left + right)/2

    ### the range breaks down into two parts left to mid and mid+1 to right 
    ### at positions 2*pos and 2*pos+1 in tree respectively

    update(2*pos , left , mid , i , j , val)
    update(2*pos + 1 , mid+1 , right , i , j , val) 
    tree[pos][0] = tree[2*pos][0] + tree[2*pos + 1][0] + tree[pos][1]*(right - left +1 ) 


def getvalue(pos , left , right , i , j ):

    ###gets sum of elements in list from index i to j in our case
    ### i will be equal to j , will see below 

    i = max(i , left)
    j=  min(j , right)
    if i > j:
        return 0
    if i==left and j==right:
        return tree[pos][0]

    mid = (left + right)/2 
    return getvalue(2*pos , left , mid , i , j) + getvalue(2*pos+1 , mid+1 , right , i , j) + tree[pos][1]*(j - i + 1)
for i in range( len(t) ):
    update(1 , 1 , N , t[i][0] , t[i][1] , t[i][2])

ans = 0

###Remember l is 1 based indexed
for i in range(1 , N+1):
   ###see we only use getvalue where i and j parameters of getvalue are same
   value = getvalue(1 , 1 , N , i , i) 
   if value < n:
       ans = ans + 1

print ans
现在,您的段树已经准备好了,我们将处理查询,然后只计算 元素小于某个值n

I = [0] * int(input())
n = int(input())
j = int(input())
t=[] 
tree=[]
for i in range(j):
   s=raw_input()
   l=s.split()
   for x in range(len(l)):
       l[x]=int(l[x])
   t.append(l)

for i in range(1,2*len(I)+1):
   tree.append([0,0])

def update(pos , left , right , i , j , val):

    ####updating segment tree to add value val in list l from index i to j

    i=max(i , left)
    j=min(j , right)
    if i > j:
       return

    if i==left and j==right:
       tree[pos][0] = tree[pos][0] + val*( j - i + 1 )
       tree[pos][1] = tree[pos][1] + val
       return

    mid = (left + right)/2

    ### the range breaks down into two parts left to mid and mid+1 to right 
    ### at positions 2*pos and 2*pos+1 in tree respectively

    update(2*pos , left , mid , i , j , val)
    update(2*pos + 1 , mid+1 , right , i , j , val) 
    tree[pos][0] = tree[2*pos][0] + tree[2*pos + 1][0] + tree[pos][1]*(right - left +1 ) 


def getvalue(pos , left , right , i , j ):

    ###gets sum of elements in list from index i to j in our case
    ### i will be equal to j , will see below 

    i = max(i , left)
    j=  min(j , right)
    if i > j:
        return 0
    if i==left and j==right:
        return tree[pos][0]

    mid = (left + right)/2 
    return getvalue(2*pos , left , mid , i , j) + getvalue(2*pos+1 , mid+1 , right , i , j) + tree[pos][1]*(j - i + 1)
for i in range( len(t) ):
    update(1 , 1 , N , t[i][0] , t[i][1] , t[i][2])

ans = 0

###Remember l is 1 based indexed
for i in range(1 , N+1):
   ###see we only use getvalue where i and j parameters of getvalue are same
   value = getvalue(1 , 1 , N , i , i) 
   if value < n:
       ans = ans + 1

print ans
对于范围内的i(len(t)):
更新(1,1,N,t[i][0],t[i][1],t[i][2])
ans=0
###记住l是基于1的索引
对于范围(1,N+1)内的i:
###请看,我们仅在getvalue的i和j参数相同的情况下使用getvalue
value=getvalue(1,1,N,i,i)
如果值
与您的算法相比,该算法的总体复杂度为O(大小(t)*logN+N) 在最坏的情况下是O(t的大小)*N)。另外,由于查询是范围更新I 延迟更新(谷歌延迟传播),这样更新和查询一次就可以保留 O(logN)

I = [0] * int(input())
n = int(input())
j = int(input())
t=[] 
tree=[]
for i in range(j):
   s=raw_input()
   l=s.split()
   for x in range(len(l)):
       l[x]=int(l[x])
   t.append(l)

for i in range(1,2*len(I)+1):
   tree.append([0,0])

def update(pos , left , right , i , j , val):

    ####updating segment tree to add value val in list l from index i to j

    i=max(i , left)
    j=min(j , right)
    if i > j:
       return

    if i==left and j==right:
       tree[pos][0] = tree[pos][0] + val*( j - i + 1 )
       tree[pos][1] = tree[pos][1] + val
       return

    mid = (left + right)/2

    ### the range breaks down into two parts left to mid and mid+1 to right 
    ### at positions 2*pos and 2*pos+1 in tree respectively

    update(2*pos , left , mid , i , j , val)
    update(2*pos + 1 , mid+1 , right , i , j , val) 
    tree[pos][0] = tree[2*pos][0] + tree[2*pos + 1][0] + tree[pos][1]*(right - left +1 ) 


def getvalue(pos , left , right , i , j ):

    ###gets sum of elements in list from index i to j in our case
    ### i will be equal to j , will see below 

    i = max(i , left)
    j=  min(j , right)
    if i > j:
        return 0
    if i==left and j==right:
        return tree[pos][0]

    mid = (left + right)/2 
    return getvalue(2*pos , left , mid , i , j) + getvalue(2*pos+1 , mid+1 , right , i , j) + tree[pos][1]*(j - i + 1)
for i in range( len(t) ):
    update(1 , 1 , N , t[i][0] , t[i][1] , t[i][2])

ans = 0

###Remember l is 1 based indexed
for i in range(1 , N+1):
   ###see we only use getvalue where i and j parameters of getvalue are same
   value = getvalue(1 , 1 , N , i , i) 
   if value < n:
       ans = ans + 1

print ans

请原谅我的坏蟒蛇

num_to_是否在所有查询中都添加常量?您应该查找段树或二叉索引树,您会在stackoverflow上找到许多类似的问题。否,对于某些查询,它是不同的。你有什么特别的链接吗?阅读这里的片段树我有一个快速的问题,我把它编辑到了我的主要问题上。谢谢,你确保了它是基于1的索引,在树中按N+1[0,0]这是正确的吗?tree=[[0,0]*(len(I)+1)]这和主要问题的编辑初始化都会创建索引器。更正了它忘记编写返回语句,现在应该可以正常工作了不是吗tree=[[0,0]*(2*len(I)+1)]