树状数组可以通过下面这个网站进行学习:
#130. 树状数组 1 :单点修改,区间查询
#130. 树状数组 1 :单点修改,区间查询 - 题目 - LibreOJ (loj.ac)
"""
https://loj.ac/p/130
单点修改,区间查询
"""
def lowbit(x: int):
return x & -x
def getsum(x):
ans = 0
while x > 0:
ans += c[x]
x -= lowbit(x)
return ans
def add(pivot, v):
while pivot <= n:
c[pivot] += v
pivot += lowbit(pivot)
if __name__ == '__main__':
n, q = map(int, input().strip().split(" "))
lst = [-1] + list(map(int, input().strip().split(" "))) # 方便下标操作
ops = [(map(int, input().strip().split(" "))) for _ in range(q)]
c = [0] * (n + 10) # 建立
res = []
# 建树
for i in range(1, n + 1):
add(i, lst[i])
del lst
for op in ops:
t, x, y = op
if t == 1:
add(x, y)
else:
res.append(getsum(y) - getsum(x - 1))
for i in res:
print(i)
#131. 树状数组 2 :区间修改,单点查询
#131. 树状数组 2 :区间修改,单点查询 - 题目 - LibreOJ (loj.ac)
"""
https://loj.ac/p/130
单点修改,区间查询
"""
def lowbit(x: int):
return x & -x
def getsum(x):
ans = 0
while x > 0:
ans += c[x]
x -= lowbit(x)
return ans
def add(pivot, v):
while pivot <= n:
c[pivot] += v
pivot += lowbit(pivot)
if __name__ == '__main__':
n, q = map(int, input().strip().split(" "))
lst = [0] + list(map(int, input().strip().split(" "))) # 方便下标操作
ops = [list(map(int, input().strip().split(" "))) for _ in range(q)]
c = [0] * (n + 10) # 建立
# O(n)版本,利用前缀和
for i in range(1, n + 1):
c[i] = lst[i] - lst[i - lowbit(i)]
for i in range(n,0,-1):
lst[i] = lst[i] - lst[i - 1]
res = []
# 建树
# O(nlogn)版本
# for i in range(1, n + 1):
# add(i, lst[i])
for op in ops:
type, t = op[0], op[1:]
if type == 1:
x, y, z = t
add(x, z)
add(y + 1, -z)
else:
t = t[0]
print(getsum(t))
#132. 树状数组 3 :区间修改,区间查询
#132. 树状数组 3 :区间修改,区间查询 - 题目 - LibreOJ (loj.ac)
"""
https://loj.ac/p/132
区间加区间和
"""
def lowbit(x):
return x & -x
def add(pivot, x, tr, n):
while pivot <= n:
tr[pivot] += x
pivot += lowbit(pivot)
def getsum(pivot, tr):
ans = 0
while pivot > 0:
ans += tr[pivot]
pivot -= lowbit(pivot)
return ans
def getAllSum(x, tr_d, tr_di):
return getsum(x, tr_d) * (x + 1) - getsum(x, tr_di)
n, q = map(int, input().strip().split(" "))
lst = [0] + list(map(int, input().strip().split(" ")))
ops = [list(map(int, input().strip().split(" "))) for _ in range(q)]
tr_d = [0] * (n + 10)
tr_di = [0] * (n + 10)
# 构造差分数组
for i in range(n, 0, -1):
lst[i] = lst[i] - lst[i - 1]
# 初始化tr_d & tr_di 时间复杂度O(nlogn)
for i in range(1, n + 1):
add(i, lst[i], tr_d, n)
add(i, lst[i] * i, tr_di, n)
# 开始操作
for op in ops:
op_type, t = op[0], op[1:],
if op_type == 1:
l, r, x = t
add(l, x, tr_d, n)
add(r + 1, -x, tr_d, n)
add(l, x * l, tr_di, n)
add(r + 1, -x * (r + 1), tr_di, n)
else:
l, r = t
res = getAllSum(r, tr_d, tr_di) - getAllSum(l - 1, tr_d, tr_di)
print(res)
1265. 数星星
"""
https://www.acwing.com/problem/content/1267/
"""
def lowbit(x):
return x & -x
def add(pivot, x, tr, n):
while pivot <= n:
tr[pivot] += x
pivot += lowbit(pivot)
def getsum(pivot, tr):
ans = 0
while pivot:
ans += tr[pivot]
pivot -= lowbit(pivot)
return ans
n = int(input())
lst = [list(map(int, input().split(" "))) for _ in range(n)]
N = 32010
tr = [0] * (N + 10)
res = []
ans = [0] * n
for x, y, in lst:
add(x + 1, 1, tr, N)
# 算出每一个星星的星级
res.append(getsum(x + 1, tr) - 1)
# 整理答案
for r in res:
ans[r] += 1
# 输出答案
for a in ans:
print(a)
LCR 170. 交易逆序对的总数
LCR 170. 交易逆序对的总数 - 力扣(LeetCode)
"""
https://leetcode.cn/problems/shu-zu-zhong-de-ni-xu-dui-lcof/
求逆序对
"""
def re_lst(lst):
"""离散化数组"""
tem = [(pivot, i) for pivot, i in enumerate(lst)]
tem.sort(key=lambda x: x[1])
for i in range(len(tem)):
lst[i] = tem[i][0] + 1 # 从1开始,方便树状数组
def lowbit(x):
return x & -x
def add(pivot, x, tr, n):
while pivot <= n:
tr[pivot] += x
pivot += lowbit(pivot)
def getSum(pivot, tr):
ans = 0
while pivot:
ans += tr[pivot]
pivot -= lowbit(pivot)
return ans
def getPairs(lst):
"""顺序对"""
n = len(lst)
tr = [0] * (n + 10)
ans = 0
for p, i in enumerate(lst):
add(i, 1, tr, n)
ans += getSum(i, tr) - 1
return ans
def getReversePairs(lst: list):
n = len(lst)
tr = [0] * (n + 10)
ans = 0
for i in range(n - 1, -1, -1):
add(lst[i], 1, tr, n)
ans += getSum(lst[i], tr) - 1
return ans
lst = [4, 3, 2, 1]
re_lst(lst)
print(lst)
# 先求顺序对
t = getPairs(lst)
print(t)
# 求逆序对
print(getReversePairs(lst))
1215. 小朋友排队
"""
https://www.acwing.com/problem/content/1217/
使用树状数组解决该问题
"""
def re_lst(lst):
"""离散化数组"""
tem = [(pivot, i) for pivot, i in enumerate(lst)]
tem.sort(key=lambda x: x[1])
for i in range(len(tem)):
lst[i] = tem[i][0] + 1 # 从1开始,方便树状数组
def lowbit(x):
return x & -x
def add(pivot, x, tr, n):
while pivot <= n:
tr[pivot] += x
pivot += lowbit(pivot)
def getSum(pivot, tr):
ans = 0
while pivot:
ans += tr[pivot]
pivot -= lowbit(pivot)
return ans
def getPairs(lst):
"""顺序对"""
n = len(lst)
tr = [0] * (n + 10)
for p, i in enumerate(lst):
add(i, 1, tr, n)
num[i] += getSum(n,tr) - getSum(i, tr) # 关键步骤
return
def getReversePairs(lst: list):
n = len(lst)
tr = [0] * (n + 10)
for i in range(n - 1, -1, -1):
add(lst[i], 1, tr, n)
num[lst[i]] += getSum(lst[i], tr) - 1 # 关键步骤
return
n = int(input())
lst = list(map(int, input().strip().split(" ")))
re_lst(lst)
num = [0] * (n + 10) # 记录交换次数的数组
# 计算逆序
getReversePairs(lst)
# 同上
getPairs(lst)
# 计算结果
res = 0
for v in num:
res += ((1 + v) * v) // 2
print(res)