题意:从N个数中,选出三个两两不同的数,求这三个数能够作为一个三角形的三边长的概率。
题解:用一个数组num[]记录大小为 i 的数出现的次数,通过 num[] 卷 num[] 得到 num2[],用 num2[i] 表示从N个数中选两个数,这两个数的和为 i 的情况数。然后考虑对三角形的计数,正向不易得到ans,可以考虑三个数不能构成三角形的情况数,那么可以对所有的非法情况根据其中最大一个数来进行分类。最后总的情况数 sum=sigma{ a[i]*presum_num2[i] }
LL a[FFT_MAXN|]; LL num[FFT_MAXN|]; LL num2[FFT_MAXN|]; LL sum[FFT_MAXN|]; int main() { int T; scanf("%d",&T); FFT::init(); while(T--) { int n; LL maxL=; memset(num,,sizeof(num)); scanf("%d",&n); ;i<n;i++) { scanf("%lld",&a[i]); maxL=max(maxL,a[i]); num[a[i]]++; } FFT::convo(num,maxL,num,maxL,num2); ;i<n;i++) num2[a[i]<<]--; ;i<=maxL*;i++) num2[i]/=,sum[i]=sum[i-]+num2[i]; LL q=(LL)n*(n-)*(n-)/; LL p=q; ;i<=maxL;i++) p-=num[i]*sum[i]; printf("%.7lf\n",(double)p/q); } }