差分 貪心 IncDec序列

2022-05-12 03:52:03 字數 1424 閱讀 4036

原題

題目描述

給定乙個長度為 n 的數列 a1,a2,…,ana1,a2,…,an,每次可以選擇乙個區間 [l,r][l,r],使下標在這個區間內的數都加一或者都減一。

求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。

輸入格式

第一行輸入正整數n。

接下來n行,每行輸入乙個整數,第i+1行的整數代表ai。

輸出格式

第一行輸出最少操作次數。

第二行輸出最終能得到多少種結果。

資料範圍

00≤ai<21474836480≤ai<2147483648

輸入樣例:41

122輸出樣例:12

思路:首先這題乙個重點,就是區間[l,r][l,r]的修改操作。因為這道題目的修改操作有乙個特性,就是只加一或者只減一,而不是+x+x,也不是−x−x,所以說我們並不需要用到高階的資料結構,線段樹和樹狀陣列,而只是需要用差分即可。

差分:差分的定義,可以見《演算法競賽高階指南》的p21頁。

介於第一版沒有差分,這裡說一下定義:對於乙個給定的數列a,它的差分數列b定義為, b[1]=a[1],b[i]=ai−ai−1(2<=i<=n)b[1]=a[1],b[i]=ai−ai−1(2<=i<=n)

這裡只說性質,也就是把序列a的區間[l,r][l,r]加d,也就是把al,al+1....aral,al+1....ar都加上d,其實就是它的差分序列b中,bl+d,br+1−dbl+d,br+1−d,其他的位置統統不改變。

因此在這道題目中,我們就可以利用這個非常有用的性質,因為我們只要求a序列中所有的數相同,而不在意這些方案具體是什麼,所以說我們就可以轉化題目,也就是將對a序列的+1,−1+1,−1操作,讓a序列相同,改成目標把b2,…,bnb2,…,bn變成全0即可,也就是a序列全部相等。而且最後得到的序列,就是這n個b1b1

貪心:因為我們有上面所說的性質,那麼我們就可以,每一次選取bi和bjbi和bj,2<=i,j<=n2<=i,j<=n,而且這兩個數,乙個為正數,乙個為負數,至於為什麼要是正負配對,因為我們是要這個b序列2~n都要為0,所以這樣負數增加,正數減少,就可以最快地到達目標為0的狀態。

至於那些無法配對的數bkbk可以選b1b1或者bnbn,這兩個不影響的數,進行修改。

所以說我們這道題目得出的答案就是,最少運算元min(p,q)+abs(p−q)=max(p,q)min(p,q)+abs(p−q)=max(p,q),然後最終序列a可能會有abs(p−q)+1abs(p−q)+1種情況。p為b序列中正數之和,而q為b序列中負數之和

**:·要開long long!!!!(別問我為什麼這麼說)

#includeusing namespace std;

const int n=1e5+10;

long long a[n],b[n],n;

int main()

IncDec序列(差分 貪心)

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

IncDec序列 差分 貪心

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

100 IncDec序列 差分 貪心

用途 主要用於給某一區間 加乙個數,或減乙個數 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...