蓝桥杯模板(二)python组

双指针

#模板:i快指针,j慢指针(快指针可以不停的移动,有个慢指针需要符合条件后才能移动)
#eg  求最长的不包含重复数字的连续子序列
# 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作
for i in range(n):
    j=0
    while j < i and check(j): #当j指针满足一一定条件后才会移动
        j+=1;
    # 每道题的具体逻辑

#https://www.cnblogs.com/bonelee/p/11789330.html

区间合并

n = int(input()) #管道问题

##区间集合,intervals = [[1,3],[2,6],[8,10],[15,18]]

intervals = [list(map(int,input().split())) for _ in range(n)]
def merge(intervals):
    if len(intervals) == 0:
        return intervals
    #排序
    intervals.sort(key=lambda x:x[0]) #左区间排序
    res = [] #存结果 操作在res中进行
    res.append(intervals[0]) #第一个先加入
    for i in range(1,len(intervals)):
        if res[-1][1] >= intervals[i][0]:#重叠
            res[-1] = [res[-1][0],max(res[-1][1],intervals[i][1])]
        else:
            res.append(intervals[i]) #不重叠直接加入
    return res

二分


#二分模板
#何时考虑:在某一值一侧全符合 另一侧全部不符合(如分巧克力,管道问题)
# 状态的决策过程或者序列是否满足单调性或者可以局部舍弃性

def check(x):  #判断x是否合适 返回的是目标值在数组中的最右边位置
    if (s[x]<=goal):
        return True
    return False
l = 0
r = len(s)-1
while l < r:
    mid = (r+l)//2
    if check(mid):
        l = mid
    else:
        r = mid+1
print(s[left])


def check(x):  #判断x是否合适 返回的是目标值在数组中的最左边位置
    if (s[x]>=goal):
        return True
    return False
l = 0
r = len(s)-1
while l < r:
    mid = (r+l)//2
    if check(mid):
        r = mid
    else:
        l = mid-1
print(s[left])


#二分查找
def b_s(ls,val):
    l = 0
    r = len(s)-1
    while l < r:
        mid  = (r+l)//2
        if ls[mid] == val:
            return mid
        elif ls[mid] > val:
            r = mid-1
        else ls[mid] < val:
            l = mid +1
    return 

树状数组

#点修区间查

n,m = map(int,input().split())#数列的长度和操作的总数

#加上一个零使数组下标从1开始,方便处理
a = [0] + list(map(int,input().split()))

s = [0]* (len(a)+5)#用于存储树状数组的信息

#计算x的二进制表示中最低位的1所代表的值
def lowbit(x):
    return x & -x

def add(i,x): #用于向树状数组中的第i个位置加上x
    while i<n:
        s[x] += x
        i += lowbit(x)

def sum_s(x):#查询前x项的和
    res = 0
    while x:
        res += s[x]
        x -= lowbit(x)
    return res
for i in range(1,n+1):
    add(i,a[i]) #更新树状数组的值

for i in range(m):
    o,l,r = map(int,input().split())
    if o == 1: #操作是1,则调用add(l,r)函数,将第l个数加上r
        add(l,r)
    else: print(sum_s(r)-sum_s(l-1)) #操作是2,则打印区间[l,r]内的所有数的和

#区间修点查

for i in range(m):
    b = list(map(int,input().split()))#操作
    if b[0] == 1: #差分的思想  某区间每一个数加上一个给定值
        add(b[1],b[3])
        add(b[2],-b[3])
    else:
        print(a[b[1]+sum_s(b[1])]) #先获取该位置的原始值,再加上前缀和

posted @ 2024-04-08 00:03  taixian  阅读(151)  评论(0)    收藏  举报