挺好的一道思維題。
分析
因為是對區間修改,多次修改肯定會超時,很容易想到差分。
那么原題的對區間修改就可以轉換為下面三個操作(均在差分數組中):
1. 任選一個數+1
2. 任選一個數-1
3. 任選兩個數+1和-1
進一步考慮題目的問題,讓原數組一樣,那么就是
a[1]的值任意,a[2]開始后面的值均為0。
再分析現有的三個操作,最多的操作數肯定是總正數之和或者總負數之和(取大的那個)
顯而易見的,因為只能選一個數進行操作。
那么我們再考慮滿足當前最少操作數的時候,能出現不同序列的數量,即a[1]的取值能有多少。
如果正數比負數多,那么正數執行操作3減少到0,額外的還能執行加法(加到a[1]身上),也可以不加(即選操作2)。那么不同的數量就是正數比負數多的部分再+1(可以一個都不加)。
反之負數也是如此,但是需要注意負數執行加,那么a[1]就是減,不能小于0。
正負一樣多,那肯定就只有一種序列了,因為要求操作數最少。
AC代碼
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;const int N=1e5+5;
int n,a[N],pos,neg;void solve(){cin>>n;for(int i=1,t;i<=n;++i){cin>>t;a[i]+=t;a[i+1]-=t;}for(int i=2;i<=n;++i)if(a[i]<0)neg+=-a[i];else pos+=a[i];cout<<max(pos,neg)<<endl;//最少操作次數if(pos>neg){//正數多cout<<pos-neg+1<<endl;}else if(pos==neg){cout<<1<<endl;}else if(pos<neg){//負數多if(neg-pos<=a[1])cout<<neg-pos+1<<endl;else cout<<a[1]+1<<endl;}
}signed main(){ios::sync_with_stdio(false),cin.tie(nullptr);int t=1;while(t--)solve();return 0;
}