【蓝桥杯】第九届 蓝桥杯 省赛 C/C++ B组 第6题 递增三元组

题目

给定三个整数数组
A = [A1, A2, … AN],
B = [B1, B2, … BN],
C = [C1, C2, … CN],
请你统计有多少个三元组(i, j, k) 满足:
1.1 <= i, j, k <= N
2.Ai < Bj < Ck

【输入格式】
第一行包含一个整数N。
第二行包含N个整数A1, A2, … AN。
第三行包含N个整数B1, B2, … BN。
第四行包含N个整数C1, C2, … CN。

对于30%的数据,1 <= N <= 100
对于60%的数据,1 <= N <= 1000
对于100%的数据,1 <= N <= 100000 0 <= Ai, Bi, Ci <= 100000

【输出格式】
一个整数表示答案

【样例输入】
3
1 1 1
2 2 2
3 3 3

【样例输出】
27

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

解题思路

题目不难。可以用一个3行100001列的数组data记录每行数字出现的次数,如data[0][5]表示A中5出现的次数。再用一个3行100001列的数组S记录data的前缀和。最后遍历B中的每一个数 Bi,使用前缀和求出A中<Bi的数的总和和C中>Bi的数的总和, 再相乘加到ans里面。

注意由于最后答案可能很大,所以ans和S都要使用long long。(曾经S没有使用long long导致N=100000的样例没过~~)最后,代码复杂度为O(n)。

代码如下:

代码

#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;

const int MAX_M = 3;
const int MAX_N = 1e5+5;
typedef long long LL;
LL Data[MAX_M][MAX_N];
LL S[MAX_M][MAX_N]; 
int N;
int nbr;
LL ans=0;

void solve() {
	scanf("%d", &N);
	int i, j, k;
	for(i=0; i<3; i++){
		for(j=0; j<N; j++){
			scanf("%d", &nbr);
			Data[i][nbr]++;
		}
	}
	S[0][0] = Data[0][0];
	S[1][0] = Data[1][0];
	S[2][0] = Data[2][0];
	for(i=0; i<3; i++){
		for(j=1; j<MAX_N; j++){
			S[i][j] = S[i][j-1] + Data[i][j];
		}
	}
	for(i=1; i<MAX_N-1; i++){
		ans+=Data[1][i]*S[0][i-1]*(S[2][MAX_N-1]-S[2][i]);
	}
	printf("%lld\n", ans);
	
}

int main() {
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值