当前位置:首页 » 《随便一记》 » 正文

【蓝桥模板】——考试倒计时3天,你和省一就差这最后10分了(差分模板)

27 人参与  2023年04月06日 09:59  分类 : 《随便一记》  评论

点击全文阅读


 大家好,我是爱分享的小蓝,欢迎交流指正~ 

全文目录?

?差分模板

?差分-树木上药

?传送锚点

 ?思路点拨

?代码详解  

 ?差分-小明的彩灯

?传送锚点​

 ?思路点拨

?代码详解 


?差分模板

差分三部曲=差分相减+转换加减+前缀相加

#差分三部曲#1.差分相减(差分公式)for i in range(len(dp)-1,0,-1):    dp[i]-=dp[i-1]#2.转换加减(区间加减→端点加减)    dp[l-1]+=v      dp[r]-=v#3.前缀相加(前缀和公式)for i in range(1,n):    dp[i]+=dp[i-1]'''dp=[1, 2, 3, 4, 5, 7, 2]+[0]首先假设有一个数组:1 2 3 4 5 7 2差分后:1 1 1 1 1 2 -5 -2一般应用场景:让你对区间 [l,r] 加减操作 N 次如:从第二个元素到第五个元素每个+3从第二个元素到第四个元素每个-2从第一个元素到第三个元素每个+1....这里我们先演示前三个:对于每个 [l,r] 区间的加减操作都转化为对端点 l,r+1 的操作从第二个元素到第五个元素每个+3:转化为:[l]+3 并且 [r+1]-3那么原序列变成了:1 1 1 1 1 2 -5 -21 4 1 1 1 -1 -5 -2然后我们按照 a[i]=a[i]+a[i-1] 复原:1 5 6 7 8 7 2 0去掉最后一项,跟原序列对比:1 2 3 4 5 7 21 5 6 7 8 7 2确实是都加上了 3。我们继续操作:从第二个元素到第四个元素每个-2转化为:[l]-2 并且 [r+1]+2那么序列变成了: 1 4 1 1 1 -1 -5 -21 2 1 1 3 -1 -5 -2然后我们按照a[i]=a[i]+a[i-1] 复原1 3 4 5 8 7 2 0与上次复原后对比:1 5 6 7 8 7 21 3 4 5 8 7 2 我们最后直接做三次,最后还原:从第二个元素到第五个元素每个+3从第二个元素到第四个元素每个-2从第一个元素到第三个元素每个+11 2 3 4 5 7 2原序列差分后:2 2 1 0 3 -1 -5 -22 号元素 + 3 6 号元素 - 32 号元素 - 25 号元素 + 21 号元素 + 1 4 号元素 - 1差分序列变成:2 2 1 0 3 -1 -5 -2复原后:2 4 5 5 8 7 5 0与原序列对比:1 2 3 4 5 7 22 4 5 5 8 7 5'''

参考资料:原理解释 样例解释


?差分-树木上药

?传送锚点

 ?思路点拨

老规矩,先来一道差集的经典例题「树木上药」,熟悉一下差分三部曲~

1、差分相减:先创建一个dp列表,相隔两个元素相减。因为这道题dp列表初始化都为0,运算之后还是0不变,所以可以跳过第一步不写,写上是为了更好理解。

2、转换加减:区间的加减转换成两个端点的加减,左端点加上权值,右端点减去权值。

3、前缀相加:将第一步的差集用前缀和还原回去,这里用到之前学过的前缀和模板。

?代码详解  

#差分-树木打药n,m=map(int, input().split())dp=[0]*n#1.差分相减(差分公式)#可以跳过不写#2.转换加减(区间加减→端点加减)for i in range(m):    l,r,v= map(int, input().split())    dp[l-1]+=v  #l的下标是l-1    dp[r]-=v    #r+1的下标是r#3.前缀相加(前缀和公式)for i in range(1,n):    dp[i]+=dp[i-1]print(sum(dp))'''input:500 3150 300 4100 200 20470 471 19print:2662'''

 ?差分-小明的彩灯

?传送锚点

 ?思路点拨

接下来,一道差集的简单题「小明的彩灯」,检验一下差分三部曲的掌握情况吧~

1、差分相减:先创建一个dp列表,差分相减直接跳过。

2、转换加减:区间彩灯的亮度加减,转化为两个端点的亮度加减。

3、前缀相加:前缀和还原回去,就完成差分模板了。

?代码详解  

#差分-小明的彩灯n,q=map(int,input().split())a=list(map(int,input().split()))dp=[0]*(n+1)for i in range(q):    l,r,x=map(int,input().split())    dp[l-1]+=x    dp[r]-=xfor i in range(1,n):    dp[i]+=dp[i-1]for i in range(n):    print(max(dp[i]+a[i],0),end=" ")'''input:5 32 2 2 1 51 3 34 5 51 1 -100print:0 5 5 6 10'''

  ​​​ 友友们,备战蓝桥最后3天,一起冲刺省赛一等奖!​​​

​​


点击全文阅读


本文链接:http://zhangshiyu.com/post/58569.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1