题目概况
题目链接: https://nanti.jisuanke.com/t/T1269
难度: 普及/提高-(普及T3)
题目分析
简化题目: 题目已经到达最简
涉及知识点: 前缀和及区间可加性
解题思路:
首先我们肯定能想到通过双层循环枚举前两个数并计算第三个数的方法,但是复杂度是O(n ^ 2),对于题目中给出的数据范围,肯定是无法通过的。
我们考虑用前缀和的方式,先统计a[1] ~ a[n]中1的出现次数,再统计a[2] ~ a[n] 中1,2组合的出现次数。最后再次循环a[3] ~ a[n] ,如果为3 ,则加上前面的1,2组合数 总数量即可。
代码要点及注释
直接看完整的,不难。有一点要注意的就是组合数不保证在int
内,所以需要开
完整代码
相关见注释。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 100010;
long long n, ans_finally; //最后的答案
long long ans1[MAXN], ans12[MAXN]; //分别表示1的出现数量和1,2的组合数量
int a[MAXN];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
ans1[i] = ans1[i - 1]; //继承
if (a[i] == 1) {
ans1[i]++; //再加
}
}
for (int i = 2; i <= n; i++) {
ans12[i] = ans12[i - 1]; //逻辑同上
if (a[i] == 2) {
ans12[i] += ans1[i - 1]; //开始算组合数的
}
}
for (int i = 3; i <= n; i++) {
if (a[i] == 3) {
ans_finally += ans12[i]; //加法原理,不懂问度娘
}
}
printf("%lld", ans_finally);
return 0;
}