ACwing 100 InDec序列 差分

2022-05-25 15:36:10 字數 1689 閱讀 8571

(題面來自acwing)

給定乙個長度為 n

'>n

的數列 a1,

a2,…

,an'>a1,a2,…,an

,每次可以選擇乙個區間 [l,r],使下標在這個區間內的數都加一或者都減一。

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

輸入格式

第一行輸入正整數n

'>n

。接下來n

'>n

行,每行輸入乙個整數,第i+1行的整數代表a

i'>ai

。輸出格式

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

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

資料範圍

0105

'>0≤a

i<

2147483648

'>0≤ai<2147483648(因為不開long long再次見到了祖宗)

0105

'>0≤a

i<

2147483648

'>看到題面之後的第一想法是差分之後暴搜方案,每次從(1~n + 1)選不同的兩個數+1/-1,目標狀態是d_2~d

0105

'>0≤a

i<

2147483648

'>_n全部為0。然而資料範圍顯然不能接受。考慮序列操作的本質:我們要將差分序列d中除第一項外全部變為0,顯然最優的方案是在d_2~d_n中

優先選擇乙個負數、乙個正數,分別+1、-1;設p、q分別為d中正、負項之和的絕對值,那麼如上的第一種操作會把p、q中較小的一方降為0,這個過程最多執行min(p, q)次。之後正/負項中有一方會有剩餘,我們可以選擇把d_1與剩餘項一同操作(相當於把原序列的某個字首全部+1/-1),也可以選擇d_(n+1)與剩餘項一同操作(相當於操作字尾),最終都可以實現d_2~d_n全部為0。這一步操作最多執行|p - q|次。那麼總的操作次數ans1滿足:

0105

'>0≤a

i<

2147483648

'>ans1 = min(p, q) + |p - q| = max(p, q)

第二問要求統計在滿足最小步數的情況下,可能產生的序列種類。由於最後序列每一項都相同,而d[1] = a[1],我們只要考慮最後d[1]有多少種即可。顯然,上述最短操作過程不分先後,並且第一種操作不會對d[1]產生影響。考慮執行第二種操作後d[1]可能的取值:d[1]最多被增加/減少|p - q|次,最少被操作0次,並且d[1]可以被操作[0, |p - q|]中的任意多次。因此d[1]的取值有|p - q| + 1種,即ans2 = |p - q| + 1。

**:#include 

#include 

#include 

#define rep(i, a, b) for(int i = a; i <= b; ++i)  

#define per(i, b, a) for(int i = b; i >= a; --i)  

#define maxn 100010  

using namespace std;  

long long d[maxn], a[maxn];  

int main()   

cout << max(p, q) << endl << abs(p - q) + 1;  

return 0;  

}  

AcWing 100 增減序列

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

AcWing100 增減序列 差分

求出 a i 的差分數列 b i 題目的目的是使 b 2,ldots,b n 都變為 0 令 p,q 分別為 中正數和負數之和的絕對值,優先在 b 2,ldots,b n 中選一對正負數操作肯定是最優的,之後再分別與 b 1或b n 配對操作 include include include incl...

AcWing100 增減序列 差分 貪心

原題鏈結 題目要求通過對區間 l,r 的操作 1或者 1 使數列中數都一樣.我們發現滿足上述要求的數列的差分陣列的a 2 n 一定是 0,0,0,a 1 是val 據此,我們可以將問題轉化成經過最少次對區間 l,r 的操作使差分陣列a變為 val,0,0,0,下面是貪心的部分 大佬的部落格講解 in...