classNode: def__init__(self, a, b,c): self.a = a self.b = b self.c = c def__repr__(self): returnf'({self.a}, {self.b}, {self.c})' t = int(input()) nodes = []
for _ inrange(t): a, b, c = map(int, input().split()) nodes.append(Node(a,b,c))
nodes = sorted(nodes, key = lambda x : (x.a, -x.b,x.c))
defmerge(left, right): global count ans = [] i = j = 0 while i < len(left) and j < len(right): if(left[i] <= right[j]): # 一定要 = ans.append(left[i]) i += 1 else: ans.append(right[j]) count += (len(left) - i) j += 1 ans.extend(left[i:]) ans.extend(right[j:]) return ans
deff(arr): iflen(arr) == 1: return arr mid = len(arr) // 2 left = f(arr[:mid]) right = f(arr[mid:]) return merge(left, right)
快排
理解 第一种快排的排序方法
fold title:C++版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
defquick_sort(l, r,arr): if l >= r: return; i ,j = l, r x = arr[l] while i < j: while i < j and arr[j] >= x: j -= 1 while i < j and arr[i] <= x: i += 1 if i < j: arr[i], arr[j] = arr[j], arr[i]
defquick_sort1(arr): iflen(arr) <= 1: return arr povit = arr[0] left = [x for x in arr[1:] if x <= povit] right = [x for x in arr[1:] if x > povit] return quick_sort1(left) + [povit] + quick_sort1(right)
建树
fold title:vector 建树
1 2 3 4 5 6 7
1. 有权 dj = [[] for _ inrange(n + 1)] dj[a].append((b,w))
2. 无权 dj[a].append(b)
二分查找
C++
lower_bound() 查找可插入元素的最小位置
upper_bound() 查找可插入元素的最大位置
binary_bound() 查找元素是否存在
PY
fold title:bisect
1 2 3 4 5
import bisect bisect.bisect_left() # 靠左 >= 严格大于等于 bisect.bisect_right() # 靠右 > 严格大于 # 从 lo -> hi x = bisect.bisect_right(a, need, lo=1, hi=i)
三分
三分用来求函数极值
一般 有 先增后减,先减后增 的特性
三分模版:
1 2 3 4 5 6 7 8
while l < r: mid1 = l + (r - l) // 3 mid2 = r - (r - l) // 3 if f(mid1) > f(mid2): r = mid2 - 1 else: l = mid1 + 1 print(f(l))
# 01 背包 for i inrange(1, n+1): for j inrange(C, w[i]-1, -1): f[j] = max(f[j], f[j - w[i]] + v[i]) # 完全背包 for i inrange(1, n+1): for j inrange(C, w[i]-1, -1): f[j] = max(f[j], f[j - w[i]] + v[i])
多重背包
问题:每一个物品有 选择次数限制 s[i]
使用二进制优化 转化成01背包
将 s[i] 使用二进制进行拆分 (k * w, k * v) k是 2 的 n次方
1 2 3 4 5 6 7 8 9 10 11
new = [] for i inrange(n): w, v, s = W[i], V[i], S[i] k = 1 while k < s: new.append((w * k, v * k)) s -= k k <<= 1 if s > 0: new.append((w * s, v * s)) # 转化成新的 01 背包
for group in groups: for j inrange(V,-1,-1): for w,v in group: if j >= w: f[j] = max(f[j],f[j - w] + v)
有依赖背包
树型DP
区间DP
数论
埃式筛
1 2 3 4 5 6 7 8 9 10 11
prime = [] is_prime = [True] * (n + 1) for i inrange(2,n): if if_prime[i]: prime.append(i) for j inrange(i * i, n + 1, i): is_prime[j] = False return prime
拆分因子
1 2 3 4 5 6 7
ans = set()
for i inrange(1, int(n ** 0.5) + 1): if n % i == 0: ans.add(i) ans.add(n // i) returnsorted(ans)
因子预处理
1 2 3 4 5 6
fac = [[] for i inrange(n + 1)]
for i inrange(1, n + 1): for j inrange(i, n + 1, i): fac[j].append(i) return fac
Python 解决字符串分割问题
巧妙的使用 split(‘char’)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
s = input().strip()
terms = s.split('+')
ans = 0 for fa in terms: s1 = fa.split('*') temp = 1 for fac in s1: if fac: temp *= int(fac) ans += temp
# NEXT[I] 表示 前 i - 1 个元素的 最长前后缀匹配长度 next = [0] * len(s2) defget_next(s2): n = len(s2) next[0] = -1 next[1] = 0 i, cn = 2,0# cn 表示 i - 1 的next值 while i < n: if s2[i - 1] == s2[cn]: next[i++] = ++cn elif cn > 0: cn = next[cn] else: next[i++] = 0
defkmp(s1, s2): n, m = len(s1),len(s2) x, y = 0, 0 get_next(s2) while x < n and y < m: if s1[x] == s2[y]: x += 1 y += 1 elif y == 0: x += 1 else: y = next[y]
n, s # n 表示 层, s 表示 种类 # 第一层什么不都存储,相当于空字符 tree = [[0]*s for i inrange(n)] # pass 表示 每一个前缀的 访问次数 pass = [0] * N # end 表示 每一个字符串的结尾 访问次数 definsert(word): cur = 1 pass[cur] += 1 for x in word: path = x - 'a' if tree[cur][path] == 0: tree[cur][path] = ++cnt cur = tree[cur][path] pass[cur] += 1 end[cur] += 1 defprenum(pre): cur = 1 for x in pre: path = x - 'a' if tree[cur][path] == 0: return0 cur = tree[cur][path] returnpass[cur]
defdelete(word): if prenum(word) > 0: cur = 1 for x in word: path = x - 'a' pass[tree[cur][path]] -= 1 ifpass[tree[cur][path]] == 0: tree[cur][path] = 0 return; cur = tree[cur][path] end[cur] -= 1
Dijkstra
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
import heapq defdj(n, g, start): dist = [float('inf')] * n dist[start] = 0 heap = [(0,start)] while heap: d, u = heapq.heappop(heap) if d > dist[u]: continue for v, w in g[u]: if dist[v] > dist[u] + w: dist[v] = dist[u] + w heapq.heappush(heap,(dist[v],v)) return dist