题解:AT_bcu30_f 数列と計算

posted on 2024-10-18 03:39:46 | under | source

来篇小清新的题解。

考虑让每个极大连续乘积段(即全用 * 连接的)的贡献挂在它最后一个元素上,记 \(f_i\) 表示以 \(i\) 为结尾的乘积段在所有情况下的价值之和,那么答案就是 \(\sum 2^{\max(0,n-i-1)}f_i\)

\(f\) 的转移是容易的:\(f_i\gets a_if_{i-1}+a_i2^{\max(0,i-2)}\)。即分讨 \(a_i\) 前面是 * 还是 +。

复杂度 \(O(n)\)

代码

#include<bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1e5 + 5, mod = 1e9 + 7;
int n, a, f[N], pw[N], ans;

signed main(){
	pw[0] = 1;
	for(int i = 1; i < N; ++i) pw[i] = pw[i - 1] * 2ll % mod;
	cin >> n;
	for(int i = 1; i <= n; ++i){
		scanf("%lld", &a);
		f[i] = (f[i - 1] * a % mod + pw[max(0ll, i - 2)] * a % mod) % mod;
		ans = (ans + f[i] * pw[max(0ll, n - i - 1)] % mod) % mod;
	}
	cout << ans;
	return 0;
}

posted @ 2026-01-15 08:16  Zwi  阅读(2)  评论(0)    收藏  举报