洛谷P8667 [蓝桥杯 2018 省 B] 递增三元组题解自用

题目描述

给定三个整数数组 A,B,C内含N个元素。

请你统计有多少个三元组 (i, j, k)(i,j,k) 满足:

  1. 1<=i,j,k<=N
  2. Ai

输入格式

第一行包含一个整数 NN。

第二行包含 N 个整数 A_1, A_2,\cdots, A_NA1​,A2​,⋯,AN​。

第三行包含 N 个整数 B_1, B_2,\cdots, B_NB1​,B2​,⋯,BN​。

第四行包含 N 个整数 C_1, C_2,\cdots, C_NC1​,C2​,⋯,CN​。

输出格式

一个整数表示答案

输入输出样例

输入 

3
1 1 1
2 2 2
3 3 3

输出 

27

说明/提示

对于100%的数据1<=N<=1e5

0<=Ai,Bi,Ci<=1e5

对于问题的分析

对于这题,通过题目所给的样例,不难推断出最终的输出数据其实就是将C数组从前到后的遍历一遍,对于C[i]找到大于多少个B数组中的数 即sum2,同理在C[i]>B中元素的基础上对B进行一个遍历,找到A中有多少小于B[i]的数,即sum1,然后将每个sum1和sum2的积相乘再相加即可得到答案。

此时我们最多想到的就是循环嵌套,但是因为N<=1e5,双重循环就可能达到了1e10会TLE,所以要利用二分查找函数 lower_bound 和 upper_bound来降低时间复杂度(lower_bound的功能是找到一个数组内大于等于target目标值的数字,并返回它的地址,upper_bound的功能就是找到一个数组内大于target目标值的数字,并返回它的地址)既然有现成的函数,肯定要利用,将三个数组进行排序,即可找出sum1和sum2,我们不妨就用B数组来联系A,C

int n;
cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a + n);
	for (int i = 0; i < n; i++) cin >> b[i]; sort(b, b + n);
	for (int i = 0; i < n; i++) cin >> c[i]; sort(c, c + n);
/*输入a,b,c三个数组,并利用sort函数对其进行排序
for (int i = 0; i < n; i++)//遍历
		{
			sum1 = lower_bound(a, a + n, b[i]) - a;//利用lower_bound找到sum1
			sum2 = n - (upper_bound(c, c + n, b[i]) - c);//sum2
			ans += sum1 * sum2;
		}

到此为止其实输出ans即可

但是 A,B,C三个数组元素的取值也是<=1e5,也就是说ans可能会超出int的范围,所以要定义long long,然而只定义ans为long long 仍然不能AC,结果问题出在了sum1和sum2上,按理说sum1和sum2代表的数量,不会超过1e5,但是必须要开long 才行,最终再输出ans,就可以AC了。

你可能感兴趣的:(题解,蓝桥杯)