数数

Gig Combinatorics

  • 题意:给\(n <= 1e6\)的一串序列,只包含\(1, 2, 3\)三种元素,然后问,一共有多少种序列,序列开头必须只有一个\(1\),结尾必须只有一个\(3\),之间至少有一个\(2\)

  • 题解:只能说自己见的少了吧,只会统计数量,然后乘或者其他的,其实这道题,先统计前面\(1\)的数量,然后再统计到\(2\)的方案数,最后遇到三就加上到\(2\)的方案数。主要是\(2\)如何理解。当前元素为\(2\),那么前面\(1\)的数量必然因为这个\(2\)多做了一次贡献,因此\(sum_2[i] += sum_1[i-1]\),除此之外,之前的\(sum_2\)还需要\(\times 2\),想一下就知道了。

  • 代码:

#include <iostream>
using namespace std;
const int N = 1e6 + 99;
typedef long long ll;
const ll mod = 1e9 + 7;
ll a[N];
ll sum1[N];
ll sum2[N];
int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	ll ans = 0;
	for (int j = 1; j <= n; j++) {
		if (a[j] == 1) {
			sum1[j] = sum1[j-1] + 1;
		} else sum1[j] = sum1[j-1];
		if (a[j] == 2) {
			sum2[j] = sum1[j-1] + sum2[j-1] * 2;
		} else sum2[j] = sum2[j-1];
		sum1[j] %= mod;
		sum2[j] %= mod;
		if (a[j] == 3) {
			(ans += sum2[j]) %= mod;
		}
	}
	cout << ans << endl;
}

posted @ 2021-01-30 17:19  u_yan  阅读(82)  评论(0编辑  收藏  举报