题目
从N个数中选3个,能组成三角形的方案数有多少。
数据范围
$3\leq N \leq 10^5$
$1\leq 数的大小 \leq 10^5$
做法
因为数的大小不超过$10^5$,所以可以用num[i]表示长度为i的数有多少个。用FFT求出num数组与自身的卷积,此卷积的第i个数即是“任意取2个数,长度为i的方案数”。而这里面包含了同一个数选2次的方案,要减去。这里面第一次选a和第二次选b与第一次选b和第二次选a算做了不同的方案,所以要将所有方案数/2。
将原来的数组排序,从小到大枚举每个数作为选择的三个数中最右边的数,不断累加答案。假设此时枚举到$a_i$,那么我们要求的就是它左边的数选2个有多少种选法使得两数之和大于$a_i$。而通过FFT的预处理,我们可以知道当2个数的位置没有要求时,和大于$a_i$的方案数为$\sum_{i>a_i}卷积[i]$,这个可以通过前缀和O(1)得到。我们只要从中减去位置不合法的方案数即可。
不合法的位置有以下几种:
- 2个数都在$a_i$右边
- 1个在左,1个在右
- 1个就是$a_i$,另一个随意
代码
|
|
注意
- FFT的数组要开4倍原数组的大小
- 当有$10^5$个相同的数时,做卷积的结果会爆
int
,需要用long long
。