最終的目的是讓整個序列相等ios
操做只有一種使\([l,r]\)區間全都\(+1\)spa
既然整個序列相等,那麼整個序列的差分序列應爲0code
操做的話就能夠轉化爲\(a[l]+=1,a[r+1]-=1\)ip
求的是最少操做次數ci
經過原數列,咱們先求一個原始的差分序列,而後每次操做使,正數-1,負數+1,這樣就使差分序列往目標:靠近 0序列
(固然差分序列第1項不用爲0,並且首項能夠爲任何數,思考爲何?)get
設正數的和p,負數絕對值和q,那麼就很容易的到一個最少操做次數 \(max(p,q)\)
(簡單描述下怎麼來的,操做\(min(p,q)\)次後,p,q中小的變爲0,還剩\(abs(p-q)\)次 ,因此最少操做次數 \(min(p,q)+abs(p-q)=max(p,q)\))io
至於最少操做後的結果class
操做\(min(p,q)\)次後,那麼必定剩下幾項不爲0
此時能夠考慮兩中狀況stream
與差分序列首項想相加減
這種狀況由於改變首項,因此最終序列會改變,故會獲得\(abs(p-q)\)種序列思考
與第\(n+1\)項相加減
這種狀況並不改變首項,只有一種序列(第n+1項不管怎麼變,都不影響最終序列,也能夠思考爲何)
總的來講會獲得\(abs(p-q)+1\)種方案
#include<iostream> using namespace std; const int maxn=1e5+10; int a[maxn];int n; int cf[maxn]; long long p=0,q=0; long abs(long x){ return x<0?-x:x; } int main(){ cin>>n; for(int i=1;i<=n;++i){ cin>>a[i]; cf[i]=a[i]-a[i-1]; } for(int i=2;i<=n;++i){ if(cf[i]>0) p+=cf[i]; if(cf[i]<0) q-=cf[i]; } cout<<max(p,q)<<endl<<abs(p-q)+1<<endl;return 0; }