hdu 4609: 3-idiots (FFT)

时间:2021-09-25 02:10:09

题目链接

题意:从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);
    }
}