100 IncDec序列 差分 貪心

2021-09-10 12:00:22 字數 1214 閱讀 3122

用途:主要用於給某一區間 加乙個數,或減乙個數 。o(1)的時間內完成

差分,實際上就是字首和的逆過程,  例如 已知字首和陣列 b, 那麼它的差分陣列 a

a1 = b1;

a2 = b2-b1;

a3 = b3-b2;

a4 = b4-b3;

an= bn-bn-1;

如果把它們相加就很容易看出: a1+a2+a3+a4+...an  = bn;

1、此題說每次在某乙個區間【l,r】內加一或減一,如果暴力做的話時間複雜度是o(n)的,所以我們可以先離線出a陣列的差分陣列b

然後 b[l]++, b[r+1]--;     這樣我們就可以保證在l,r,之間的a陣列每乙個數都是加了1,的   然後 b[r+1]--,是使r之後的數消除這種加1的影響。

2、要使最後的數都一樣,那麼b陣列中的b2--->bn  一定全 0

因為 b2 = a2-a1;

b3 = a3-a2;

bn = an-an-1;

如果全0 的話, a1=a2=a3=....................=an

所以我們可以用貪心的思想,來使得b中所有數變成零。  我們知道我們在做 b[l]++, b[r+1]--;操作的時候,要找兩個數配對,那麼 負數++,正數--,是不是就最快了。  但是最終結果可能依然不是全 0 的,因為 abs(sum(正數)) 可能 != abs(sum(負數))

所以,我們可以 讓最後不等於0 的數全和 b1|| bn+1   來換。 

所以 ans1 = min(pos,neg)+abs(pos-neg)

ans2 = abs(pos-neg)+1;                        ///       如果最後剩 3  ----->   (0,3)(1,2)(,2,1)(,3,0)  這4種方案來選擇 b1還是 bn+1

#include#include#include#include#define ll long long 

using namespace std;

const int n = 100010;

ll a[n];

int main()

for(int i=n;i>1;i--)

ll pos = 0 , neg = 0;

for(int i=2;i<=n;i++)

cout

}

藍書 100 IncDec序列

差分陣列的巧妙運用 讓所有數都相同即 讓差分陣列bi,b2 bn都等於0.每次操作相當於選擇i,j.bi bj 為了讓b2 bn都等於0 正數之和 p,負數之和q 最少操作次數一定是 先選擇一正一負,抵消,然後剩的全正或者全負,與b1 bn 1,進行操作。最少次數為 p q 由於選擇b1,bj 和b...

IncDec序列(差分 貪心)

原題鏈結 題目大意 給定乙個序列,可以在其連續子串行上進行加一或者減一操作,求使整個序列變成相同數的最小運算元和種數。思路首要要明確是對 l,r 序列進行加一或者減一操作,可以聯想到字首和,我們對乙個陣列b的第l項進行減一操作,第r 1項進行加一操作,這樣作用到b陣列的字首和序列就是連續的區間段 l...

IncDec序列 差分 貪心

給定乙個長度為 n 的數列 a1,a2,an 每次可以選擇乙個區間 l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。第一行輸入正整數n。接下來n行,每行輸入乙個整數,第i 1行的整數代表ai。第...