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)还需要( imes 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;
}