藍橋杯模板(二)python組

taixian發表於2024-04-08

雙指標

#模板: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])]) #先獲取該位置的原始值,再加上字首和