區間加
鏈接:https://ac.nowcoder.com/acm/contest/4911/C
思路
分析每個元素與目標值之間的差值,可知相鄰的兩個元素之間差值不超過1,我們想到用差分數組求解本題;
首先用數組 記錄第個元素與目標值之間的的差值,然後對相鄰數組作差分,記爲數組;
爲了理解方便,我們將本題轉化爲左右括號放置問題,包含元素的左右括號對數(即該元素左邊左括號與右括號數目的差值)代表元素加1的次數,假設爲當前未被匹配的左括號數目,爲第個元素的方案數,有以下3種情況:
若,則第個元素比第個元素大1,則第個元素要多加一次,所以在其左邊的左括號數目加1即未匹配的左括號數;
若,則第個元素比第個元素小1,則第個位置放一個右括號,與此同時未匹配的左括號數減1,;
若,說明第個元素與第個元素相等,此時有兩種方案,一種是什麼都不做,另外一種是第個位置放上左右括號,因此
代碼
#include <iostream>
#include <cmath>
using namespace std;
#define MAX 2010
#define mo 998244355
int res[MAX], b[MAX];
int n, m;
int main(){
cin>>n>>m;
for(int i = 1; i <= n; i++){
cin>>res[i];
res[i] = m - res[i];
}
for(int i = 0; i <= n; i++) b[i] = res[i+1] - res[i];
int now = 0;
long long ans = 1;
for(int i = 0; i < n; i++){
if(abs(b[i]) > 1){
cout<<"0"<<endl;
return 0;
}
if(b[i] == 0) ans = ans * (now + 1) % mo;
if(b[i] == 1) now++;
if(b[i] == -1) ans = ans * now-- % mo;
}
cout<<ans<<endl;
return 0;
}