当前位置: 首页 > news >正文

蓝桥杯 之 前缀和与查分

文章目录

  • 题目
    • 求和
    • 棋盘
    • 挖矿

  • 前缀和有利于快速求解 区间的和、异或值 、乘积等情况
  • 差分是前缀和的反操作

前缀和

  • 一维前缀和:
# 原始的数组num,下标从1到n
n = len(num)
pre = [0]*(n+1)
for i in range(n):
	pre[i+1] = pre[i] + num[i]
# 如果需要求解num[l] 到num[r] 的区间和
ans = pre[r] - pre[l-1]
  • 二维前缀和
# 原本的数组是n*m形状的

pre = [[0]*(m+1) for _ in range(n+1)]

for i in range(n):
	for j in range(m):
		pre[i+1][j+1] = pre[i][j+1] + pre[i+1][j] - pre[i][j] + num[i][j]

前缀和的应用:

  • 当你想在一个区间进行统一的加上一个数或者减去一个数的时候,一个个操作会很慢,并且涉及多次操作的时候更新很麻烦,但是我们可以结合这个差分和前缀和进行快速求解

  • 一维:

# 在区间l到r之间同时都加上a,那么我们只需在num[l] + a,在num[r+1] -a
# 然后求解前缀和即可,就可以得到每个位置的最后的值
  • 二维:
# 1<=x1<=x2<=y1<=y2<=n
# 在x1,y1 到 x2,y2 之间都加上一个数
num[x1][y1] += a
num[x2+1]y2+1] +=a
num[x1][y2+1] -=a
num[x2+1][y1] -=a


差分:

  • 一维差分:
# 1<=l<=r<=n ,那么区间l到r之间的和值为
ans = pre[r] - pre[l-1]
  • 二维查分:
# 
ans = pre[x2][y2] - pre[x2][y1] - pre[x1][y2] + pre[x1][y1]

题目

求和

求和

在这里插入图片描述

思路分析:

  • 首先直接暴力是肯定不行的,所以得考虑转换?发现可以提取相同的元素,然后使用这个前缀和进行优化即可
import os
import sys

# 请在此输入您的代码

# 提取公因式,你会发现 ans = a1*(a2+···an) + a2*(a3+···an) + an-1*(an)

n = int(input())
num = list(map(int,input().split()))

pre = [0]*(n+1)
for i in range(n):
  pre[i+1] = pre[i] + num[i]

ans = 0
for i in range(n-1):
  ans += num[i]*(pre[n]-pre[i+1])
print(ans)


棋盘

棋盘

在这里插入图片描述

思路分析:

  • 这个题目得使用到这个二维的前缀和与查分进行优化
import os
import sys

# 请在此输入您的代码

# 其实和这个,异或操作是类似的
# 0表示白色,1表示黑色

n,m = map(int,input().split())

num = [[0]*(n+1) for _ in range(n+1)]

for _ in range(m):
  x1,y1,x2,y2 = map(int,input().split())
  x1,y1,x2,y2 = x1-1,y1-1,x2-1,y2-1
  num[x1][y1] += 1
  num[x2+1][y2+1]     +=1
  num[x1][y2+1]   -=1
  num[x2+1][y1]   -=1

# 求解二维前缀和
dp = [[0]*(n+1) for _ in range(n+1)]

for i in range(n):
  for j in range(n):
    dp[i+1][j+1] = (dp[i+1][j] + dp[i][j+1] - dp[i][j] + num[i][j])%2

for i in range(1, n + 1):
    row = "".join(str(dp[i][j]) for j in range(1, n + 1))
    print(row)


挖矿

挖矿

在这里插入图片描述

思路分析:

  • 首先明确一个问题,在坐标轴上移动,最多只能转向一次:证明,设你转向多次之后到达左端点是 l,到达右端点的坐标是 r,如果你直接一开始不转向,直接到达左端点l,然后再直接向后转向右边,那么到达的距离是肯定比r大的
import os
import sys

# 请在此输入您的代码
n,m = map(int,input().split())
num = list(map(int,input().split()))
# 开的空间
l ,r = [0]*(m + 1),[0]*(m + 1)

iszero = 0

for i in num:
  if i > 0 and i <= m:
    r[i] += 1
  if i < 0 and abs(i) <= m:
    l[abs(i)] += 1
  if i == 0:
    iszero = 1

# 计算出其中的左和右可以到达的位置所能得到的矿
for i in range(1,m+1):
  r[i] += r[i-1]
  l[i] += l[i-1]
ans = 0

# 枚举可以到达的端点,注意左边和右边
for j in range(1,m//2 + 1):
  ans = max(ans,r[j] + l[m-2*j],l[j] + r[m-2*j])

print(ans+iszero)

相关文章:

  • 智谱AI-大模型调用
  • Linux的缓存I/O和无缓存IO
  • 前端监控体系搭建
  • 游戏树搜索与优化策略:Alpha-Beta剪枝及其实例分析
  • DeepSeek×博云AIOS:突破算力桎梏,开启AI普惠新纪元
  • 昇思25天学习打卡营第33天|共赴算力时代
  • 前端性能优化之同时插入100000个元素页面不卡顿
  • my学习网址
  • 2025-3-5 leetcode刷题情况(贪心算法--简单题目)
  • 【监督学习】XGBoost 步骤及matlab实现
  • AI人工智能与实验室应用场景分析
  • 烟花燃放安全管控:智能分析网关V4烟火检测技术保障安全
  • jsp使用+返回or使用数据+日志输出
  • 从0开始的操作系统手搓教程21:进程子系统的一个核心功能——简单的进程切换
  • 数据库监控工具——PMM
  • 宠物医疗对接DeepSeek详细方案
  • 【Linux】进程间通信 续
  • FormData获取表单,发现有些字段没有获取到,
  • 鸿蒙Android4个脚有脚线
  • Gitlab配置personal access token
  • WordPress写文章一直转/信息流优化师是干什么的
  • 定制版网站建设详细报价单/网页设计代码大全
  • wordpress页面位置/成都做整站优化
  • 深圳网站设计公司电/搜索引擎优化是指
  • 夫妻做网站/sem是什么方法
  • vps云主机可以做网站/产品线上营销推广方案