差分真妙,是字首和的逆過程
例如: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
那麼差分還有什麼意思勒,兩個數的差!那麼所有數之間的差如果都為0的意思,不就是所有數相等??
那麼區間加1減一,不就是差分的某兩個數進行+1,-1?
那這麼做到最少次數勒,那不就是先把能匹配的正負給匹配了,然後剩的不能匹配的就靠虛擬最後乙個數拯救世界啦,若所剩為加,那就瘋狂最後乙個數減一唄,同理的瘋狂加一咯,
1、如果用p來記錄正操作次數,q來記錄負操作次數,那麼最少次數不就是max(p,q)
2、那麼在最小操作的情況下最多有幾種情況呢,你會發現,正負匹配的時候,改變的數是固定方向和數值的,所以對情況不影響,那麼不匹配的呢栗子找規律!(採用虛設最後乙個數)
例如:a: 1 2 3 => 1 2 2 => 1 1 1
b: 1 1 0 => 1 0 -1 => 0 0 -2
a: 1 2 3 => 2 2 3 => 3 3 3
b: 1 1 0 => 0 1 0 => 0 0 0
a: 1 2 3 => 2 2 3 => 2 2 2
b: 1 1 0 => 0 1 0 => 0 0 -1
三種情況!發現了啥?貌似從最後乙個虛設的數就特別清楚的看出來情況有0到abs(p-q)種!
所以也就是abs(p-q) +1
**如下:
#include #include #include using namespace std;
typedef long long ll;
const int n = 1e5+10;
ll a[n],b[n];
int main()
printf("%lld\n%lld",max(q,p),abs(q-p)+1);
return 0;
}
增減序列(IncDec序列)
題目 給定乙個長度為 n 的數列 a1,a2,an,每次可以選擇乙個區間 l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。輸入格式 第一行輸入正整數n。接下來n行,每行輸入乙個整數,第i 1行的...
高階指南 最大子串行
暴力思想就是求字首和,然後從左到右列舉終點,暴力得以每個點為終點的前m個數的和的最大值 優化第二步,從左到右是有順序的,我們可以考慮維護乙個佇列,每次將乙個點的字首和扔進去,到某個點時,看看前面m個裡的最小字首和即可,而當我們扔數的時候,又發現,扔乙個數進去,如果它比佇列裡面的一些數大,則前面那些比...
演算法競賽高階指南 Inc序列
給定乙個長度為 n 的數列 a1,a2,an,每次可以選擇乙個區間 l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。第一行輸入正整數n。接下來n行,每行輸入乙個整數,第i 1行的整數代表ai。第...