题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4609

题意:给出n个正整数(数组A)。每次随机选出三个数。问这三个数能组成三角形的概率为多大?

思路:求出有多少种选择的方案,除以总选择方案即可。用num[i]表示长度为i的出现几次。

对于样例1 3 3 4,我们得到num={0,1,0,2,1},

对num求卷积,得到:num={0,0,1,0,4,2,4,4,1}。此时的num[i]表示选择两个数和为i的选择方案的种数。 但是这里有重复的:

(1)两次不能选同一个数,这种情况要删去;

(2)对于两个数x和y,先选x后选y和先选y后选x,所以多算了一倍。

减去上面两种重复之后,我们得到:num={0,0,0,0,2,1,1,2}。接着设sum[i]为num的前缀和。接着将给出的数组A排序,开始统计答案。对于A[i]我们认为三个数中它是最大的,因此我们要选出在i之前的两个数使得其和大于A[i],首先大于A[i]的情况有sum[Maxlen]-sum[A[i]],然后要减去重的:

(1)一个选了i后面的一个选了i前面的;

(2)一个选了i另一个随便;

(3)两个都是i后面的。

struct node
{
    double x,y;
    
    node(double _x=0.0,double _y=0.0)
    {
        x=_x;
        y=_y;
    }
    
    node operator+(node a)
    {
        return node(x+a.x,y+a.y);
    }
    
    node operator-(node a)
    {
        return node(x-a.x,y-a.y);
    }
    
    node operator*(node a)
    {
        return node(x*a.x-y*a.y,x*a.y+y*a.x);
    }
};

node A[N];
int L;

int reverse(int x)
{
    int ans=0,i;
    FOR0(i,L) if(x&(1<<i)) ans|=1<<(L-1-i);
    return ans;
}

void bitReverseCopy(node a[],int n)
{
    int i;
    FOR0(i,n) A[i]=a[i];
    FOR0(i,n) 
    {
        a[reverse(i)]=A[i];
    }
}

void fft(node a[],int n,int on)
{
    bitReverseCopy(a,n);
    int len,i,j,k;
    node x,y,u,t;
    for(len=2;len<=n;len<<=1)
    {
        x=node(cos(-on*2*PI/len),sin(-on*2*PI/len));
        for(j=0;j<n;j+=len)
        {
            y=node(1,0);
            for(k=j;k<j+len/2;k++)
            {
                u=a[k];
                t=y*a[k+len/2];
                a[k]=u+t;
                a[k+len/2]=u-t;
                y=y*x;
            }
        }
    }
    if(on==-1)
    {
        FOR0(i,n) a[i].x/=n;
    }
}

node a[N];
int d[N],n,m;
i64 num[N],sum[N];

int main()
{
    rush()
    {
        RD(n);
        clr(num,0);
        int i;
        FOR0(i,n) RD(d[i]),num[d[i]]++;
        sort(d,d+n);
        int len=d[n-1]+1;
        m=1; L=0;
        while(m<2*len) m<<=1,L++;
        FOR0(i,len) a[i]=node(num[i],0);
        for(i=len;i<m;i++) a[i]=node(0,0);
        fft(a,m,1);
        FOR0(i,m) a[i]=a[i]*a[i];
        fft(a,m,-1);
        FOR0(i,m) num[i]=(i64)(a[i].x+0.5);
        m=d[n-1]<<1;
        FOR0(i,n) num[d[i]<<1]--;
        FOR1(i,m) num[i]>>=1,sum[i]=sum[i-1]+num[i];
        i64 ans=0;
        FOR0(i,n) 
        {
            ans+=sum[m]-sum[d[i]];
            ans-=(i64)i*(n-i-1);
            ans-=n-1;
            ans-=(i64)(n-1-i)*(n-2-i)/2;
        }
        i64 Sum=(i64)n*(n-1)*(n-2)/6;
        PR(1.0*ans/Sum);
     }
}

HDU 4609 3-idiots(FFT)的更多相关文章

  1. HDU 5763 Another Meaning(FFT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5763 [题目大意] 给出两个串S和T,可以将S串中出现的T替换为*,问S串有几种表达方式. [题解 ...

  2. 2019.01.02 bzoj3513: [MUTC2013]idiots(fft)

    传送门 fftfftfft经典题. 题意简述:给定nnn个长度分别为aia_iai​的木棒,问随机选择3个木棒能够拼成三角形的概率. 思路:考虑对于木棒构造出生成函数然后可以fftfftfft出两个木 ...

  3. A * B Problem Plus HDU - 1402 (FFT)

    A * B Problem Plus HDU - 1402 (FFT) Calculate A * B.  InputEach line will contain two integers A and ...

  4. 快速傅里叶(FFT)的快速深度思考

    关于按时间抽取快速傅里叶(FFT)的快速理论深度思考 对于FFT基本理论参考维基百科或百度百科. 首先谈谈FFT的快速何来?大家都知道FFT是对DFT的改进变换而来,那么它究竟怎样改进,它改进的思想在 ...

  5. HDU 5938 Four Operations(四则运算)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  6. HDU 5775 Bubble Sort(冒泡排序)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  7. HDU 1711 Number Sequence(数列)

    HDU 1711 Number Sequence(数列) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...

  8. HDU 1005 Number Sequence(数列)

    HDU 1005 Number Sequence(数列) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...

  9. 【BZOJ3527】力(FFT)

    [BZOJ3527]力(FFT) 题面 Description 给出n个数qi,给出Fj的定义如下: \[Fj=\sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{ ...

  10. 【BZOJ4827】【HNOI2017】礼物(FFT)

    [BZOJ4827][HNOI2017]礼物(FFT) 题面 Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每 ...

随机推荐

  1. iOS 开发中的问题

    错误提示: Your build settings specify a provisioning profile with the UUID “39642B69-0278-4265-8392-4B28 ...

  2. 首次发布App,In-App Purchase 无法submit for review 问题的解决方案

    原地址:http://blog.csdn.net/blucenong/article/details/7819195 一个IDP首次create app 然后首次create new IAP的时候,我 ...

  3. Python日志输出——logging模块

    Python日志输出——logging模块 标签: loggingpythonimportmodulelog4j 2012-03-06 00:18 31605人阅读 评论(8) 收藏 举报 分类: P ...

  4. 压测2.0:云压测 + APM = 端到端压测解决方案

    从压力测试说起 压力测试是确立系统稳定性的一种测试方法,通常在系统正常运作范围之外进行,以考察其功能极限和隐患.与功能测试不同,压测是以软件响应速度为测试目标的,尤其是针对在较短时间内大量并发用户的访 ...

  5. light oj 1140 - How Many Zeroes? 数位DP

    思路:dp[i][j]:表示第i位数,j表示是否有0. 代码如下: #include<iostream> #include<stdio.h> #include<algor ...

  6. 线段树(区间合并) POJ 3667 Hotel

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  7. centOS学习part3:远程工具VNC的安装与配置

    0 上一篇(http://www.cnblogs.com/souvenir/p/3875484.html)我们介绍了通过yum安装JDK的实例,初步见识了yum命令的强大.本章我们将继续使用yum命令 ...

  8. lintcode:等价二叉树

    等价二叉树 检查两棵二叉树是否等价.等价的意思是说,首先两棵二叉树必须拥有相同的结构,并且每个对应位置上的节点上的数都相等. 样例 1 1 / \ / \ 2 2 and 2 2 / / 4 4 就是 ...

  9. Visual Studio 2010 快捷键

    Visual Studio 2010 快捷键: CTRL + SHIFT + B 生成解决方案CTRL + F7 生成编译CTRL + O 打开文件CTRL + SHIFT + O 打开项目CTRL ...

  10. 学了C语言,如何写个程序计算出每个月的第一个星期一对应的日期

    在前面,我们分别利用泰勒公式和C标准库中的mktime()函数推算了某个特定日期所对应的星期几,刚做完这些,就又遇到了一个与日期相关的新任务: 老板把每个月例会的时间定在了每个月的第一个星期一,他让我 ...