CodeForces - 1485F

SmileMask發表於2024-07-15

題目大意

給定陣列 \(b\),求有多少 \(a\) 陣列滿足 \(a_i=b_i \ or\ \sum\limits_{k=1}^i a_k=b_i\)

分析

既然有字首和,不妨將字首和計入狀態中,設 \(dp_{i,j}\) 為前 \(i\) 個字首和為 \(j\) 的方案數。
考慮兩種條件的轉移方程。

  • 若選第一種,有 \(dp_{i,j}=dp_{i-1,j-b_i}\)
  • 若選第二種,有 \(dp_{i,b_i}=\sum\limits_{k=-\infty}^{+\infty} dp_{i-1,k}\)

此處 \(dp_{i,b_i}\) 會多算一次 \(dp_{i-1,0}\),需要減去。
直接實現這個 \(dp\) 顯然不現實,挖掘其中性質,發現第一種條件即為將原本的數列平移,第二種也只是單點賦值。

由上,考慮記錄一個 \(pos\) 為陣列偏移度,一個 \(tot\) 為總方案數。
那麼顯然 \(dp_{i,b_i}\) 即為 \(tot\),每次動態更新 \(tot\) 即可

程式碼


map <int,int> f;

void Main(){
	f.clear();
	f[0]=tot=1;
	n=rd,pos=0;
	for(int i=1;i<=n;i++){
		b=rd,pos+=b;
		int x=(tot-f[b-pos]+mod)%mod;
		f[b-pos]=tot;
		tot=(tot+x)%mod;
	}
	cout<<tot<<endl;
}