目錄
- 前置知識
- 進入正題
- 實戰演練
前置知識
給定區間 [ l, r ],讓我們把數組中的[ l, r ] 區間中的每一個數加上c,即 a[ l ] + c , a[ l + 1 ] + c , a[ l + 2] + c , a[ r ] + c;
怎么做?很簡單,差分一下即可
還不會的小伙伴點此進入學習
進入正題
進階一下:
給定區間 [ l, r ],把數組[ l, r ] 區間中的數加上一個首項s、末項e、公差為d的等差數列,
即 a[ l ] + s , a[ l + 1 ] + s+d , a[ l + 2 ] + s+2d ······a[ r ] + e
怎么實現?先給出結論
a[l] += s,
a[l + 1] += d - s
a[r + 1] -=d + e
a[r + 2] += e
再對a數組做兩次前綴和,即得到ans
為何?
下面聽我娓娓道來~
簡單舉個例子:
假設數組a=【0,0,0,0,0,0,0,0】
現要求對 a[1] 到 a[5] 這5個數字 分別加上以s為首項,d為公差,e為末項的等差數列,即a=【0,s,s+d,s+2d,s+3d,s+4d(e),0,0】
如何得到呢?我們先做一次差分試試:
diff1=【0,s,d,d,d,d,-e,0】什么也看不出來對吧。
再對差分數組做差分:
diff2=【0,s,d-s,0,0,0,-e-d,e】
哎,這不是一開始所進行的操作嗎?
a[1]+=s
a[2]+=d-s
a[6]-=d+e
a[7]+=e
一切終成閉環
好了,實際運用的時候到了
實戰演練
P4231 三步必殺 https://www.luogu.com.cn/problem/P4231
不了解異或運算可點此進入
題解code:
n, m = map(int, input().split())
ans = [0] * (n + 3)
for i in range(m):l, r, s, e = map(int, input().split())d = int((e - s) / (r - l))ans[l] += sans[l + 1] += d - sans[r + 1] -= d + eans[r + 2] += e # 實現等差數列差分for i in range(1, len(ans)):ans[i] += ans[i - 1]
for i in range(1, len(ans)):ans[i] += ans[i - 1] # 兩次前綴和xor = 0
for i in ans:xor ^= i
print(f'{xor} {max(ans)}')
如果有更多問題或需要進一步的幫助,可以在評論區留言討論哦!
如果喜歡的話,請給博主點個關注 謝謝