題目
給定乙個長度為 n 的數列 a1,a2,…,an,每次可以選擇乙個區間 [l,r],使下標在這個區間內的數都加一或者都減一。
求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。
輸入格式
第一行輸入正整數n。
接下來n行,每行輸入乙個整數,第i+1行的整數代表ai。
輸出格式
第一行輸出最少操作次數。
第二行輸出最終能得到多少種結果。
資料範圍
0< n ≤ 10^5,
0≤ ai <2147483648
輸入樣例:41
122輸出樣例:12
解析:思路:差分。假如乙個序列所有數是相等的,那麼差分之後可能只有delt[1] != 0,其他的必為0,那最少的操作次數肯定是差分陣列中的正數與負數比較後最大的那個,因為每次只能加一或減一,可以拿乙個例子來解釋,比如現在的序列是:3 2 2 3,這裡一眼可以看出最少只用操作一次,就是把l = 2,r = 3的區間進行+1就全部變為3,實際上此時的差分陣列是delt[1] = 3,delt[2] = -1, delt[3] = 0,delt[4] = 1,那其實我們可以利用差分的性質,在l = 2的陣列+1,那在r = 4的陣列-1就都變為0,而實際上操作的區間是[2,3],這個解釋是在了解差分原理後進行解析的。所有差分陣列中正負抵消後就看還剩下正的差分陣列還是負的。不過這道題還需要求出最少的操作有多少種結果,答案是:abs(差分陣列中的正數和 - 差分陣列中的負數和) + 1,這我真的想不到,不過看了題解後,我是這樣理解的:拿樣例來說,它的差分陣列是1,0,1,0,那顯然最少只用操作一次就可以了,接下來差分陣列的正數和(不看第乙個差分陣列,因為第乙個不影響)是1,然後假如我們讓l = 1加上1,r = 3減去1,那此時差分陣列就是2,0,0,0,得到的序列是(2,2,2,2),假如我在l = 3減去1,而在r = 無窮大的數加上1,那現在差分陣列就是1,0,0,0,得到的序列是(1,1,1,1),挺有意思的~可以多找幾個例子,你就能發現其中的奧秘!
ac**:
#includetypedef long long ll;
const int maxn = 1e5 + 7;
ll a[maxn], delt[maxn];
ll n, pos, neg;
int main()
for(int i = 2; i <= n; i++)
printf("%lld\n%lld", std::max(pos, neg), abs(pos - neg) + 1);
return 0;
}
本來這週的訓練是差分的,不過這週找的題目翻車了,只有幾道是差分的題,其他的用到其他的知識點去了,然後剩下的差分比較easy,就沒寫題解了,期末周了,要好好複習嗷 高階指南 Incdec序列(增減序列) 差分
差分真妙,是字首和的逆過程 例如 b 3 a 3 a 2 b 2 a 2 a 1 b 1 a 1 你會發現 a 3 b 3 b 2 b 1 哇哦是不是發現新大陸?還有更妙的 字首和的 l,r 加d 你會發現,等價於 差分的 l d,r 1 d 也就是a l r d b l d b r 1 d 那麼差...
增減序列 IncDec Sequence
題意 給定乙個長度為 n 的數列 a1,a2,an,每次可以選擇乙個區間 l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。分析 每次任意選兩個數,乙個加上1,另外乙個減去1 把b 2 到b n ...
100 增減序列
求出 a 的差分序列 b,其中 b1 a1,bi ai ai 1 2 i n 令 bn 1 0。題目對序列 a 的操作,相當於每次可以選出 b1,b2,bn 1 中的任意兩個數,乙個加一,另乙個減一。目標是把 b2,b3,bn 變為全零。最終得到的數列 a 就是由 n 個 b1 構成的。從 b1,b...