题目描述

给定n个长度分别为a_i的木棒,问随机选择3个木棒能够拼成三角形的概率。

输入

第一行T(T<=100),表示数据组数。
接下来若干行描述T组数据,每组数据第一行是n,接下来一行有n个数表示a_i。
3≤N≤10^5,1≤a_i≤10^5

输出

T行,每行一个整数,四舍五入保留7位小数。

样例输入

2
4
1 3 3 4
4
2 3 3 4

样例输出

0.5000000
1.0000000


题解

FFT

考虑什么样的3根木棍不能构成三角形:最长边大于等于其余两边之和。

因为长度只有$10^5$,因此可以直接记录由两根木棒拼成某长度的方案数,然后直接求前缀和统计答案即可。

但是朴素的统计方案数的时间复杂度是$O(n^2)$的,会TLE。

考虑到两边的长度s2[]和一边的长度s1[]的卷积有关,因此可以先使用FFT求某长度的个数s1[]的卷积,然后由于两根相同的木棒统计到了答案中,需要减掉;其余的方案出现了2次,需要再除以2.

最后求前缀和统计答案即可。注意需要long long。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
typedef long long ll;
const int len = 262144;
const double pi = acos(-1);
struct data
{
double x , y;
data() {}
data(double x0 , double y0) {x = x0 , y = y0;}
data operator+(const data &a)const {return data(x + a.x , y + a.y);}
data operator-(const data &a)const {return data(x - a.x , y - a.y);}
data operator*(const data &a)const {return data(x * a.x - y * a.y , x * a.y + y * a.x);}
}a[N << 2];
int w[N];
ll sum[N << 2];
void fft(int flag)
{
int i , j , k;
for(i = k = 0 ; i < len ; i ++ )
{
if(i > k) swap(a[i] , a[k]);
for(j = len >> 1 ; (k ^= j) < j ; j >>= 1);
}
for(k = 2 ; k <= len ; k <<= 1)
{
data wn(cos(2 * pi * flag / k) , sin(2 * pi * flag / k));
for(i = 0 ; i < len ; i += k)
{
data w(1 , 0) , t;
for(j = i ; j < i + (k >> 1) ; j ++ , w = w * wn)
t = w * a[j + (k >> 1)] , a[j + (k >> 1)] = a[j] - t , a[j] = a[j] + t;
}
}
}
void work()
{
int i;
fft(1);
for(i = 0 ; i < len ; i ++ ) a[i] = a[i] * a[i];
fft(-1);
for(i = 0 ; i < len ; i ++ ) a[i].x /= len;
}
int main()
{
int T;
scanf("%d" , &T);
while(T -- )
{
memset(a , 0 , sizeof(a));
int n , i;
ll ans = 0;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &w[i]) , a[w[i]].x ++ ;
work();
for(i = 1 ; i <= n ; i ++ ) a[w[i] * 2].x -- ;
for(i = 1 ; i < len ; i ++ ) sum[i] = sum[i - 1] + (ll)(a[i].x / 2 + 0.1);
for(i = 1 ; i <= n ; i ++ ) ans += sum[w[i]];
printf("%.7Lf\n" , 1 - (long double)ans / ((long double)n * (n - 1) * (n - 2) / 6));
}
return 0;
}

【bzoj3513】[MUTC2013]idiots FFT的更多相关文章

  1. 【BZOJ3160】万径人踪灭(FFT,Manacher)

    [BZOJ3160]万径人踪灭(FFT,Manacher) 题面 BZOJ 题解 很容易想到就是满足条件的子序列个数减去回文子串的个数吧... 至于满足条件的子序列 我们可以依次枚举对称轴 如果知道关 ...

  2. 【BZOJ3527】力(FFT)

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

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

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

  4. bzoj 3513: [MUTC2013]idiots FFT

    bzoj 3513: [MUTC2013]idiots FFT 链接 bzoj 思路 参考了学姐TRTTG的题解 统计合法方案,最后除以总方案. 合法方案要不好统计,统计不合法方案. \(a+b< ...

  5. 【Matlab】快速傅里叶变换/ FFT/ fftshift/ fftshift(fft(fftshift(s)))

    [自我理解] fft:可以指定点数的快速傅里叶变换 fftshift:将零频点移到频谱的中间 用法: Y=fftshift(X) Y=fftshift(X,dim) 描述:fftshift移动零频点到 ...

  6. 【BZOJ】3160: 万径人踪灭 FFT+回文串

    [题意]给定只含'a'和'b'字符串S,求不全连续的回文子序列数.n<=10^5. [算法]FFT+回文串 [题解]不全连续的回文子序列数=回文子序列总数-回文子串数. 回文子串数可以用回文串算 ...

  7. 【BZOJ4624】农场种植 FFT

    [BZOJ4624]农场种植 Description 农夫约翰想要在一片巨大的土地上建造一个新的农场. 这块土地被抽象为个 R*C 的矩阵.土地中的每个方格都可以用来生产一种食物:谷物(G)或者是牲畜 ...

  8. 【BZOJ3160】万径人踪灭 Manacher+FFT

    [BZOJ3160]万径人踪灭 Description Input Output Sample Input Sample Output HINT 题解:自己想出来1A,先撒花~(其实FFT部分挺裸的) ...

  9. bzoj 3513 [MUTC2013]idiots FFT 生成函数

    [MUTC2013]idiots Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 806  Solved: 265[Submit][Status][Di ...

随机推荐

  1. python爬虫之路——初识lxml库和xpath语法

    lxml库:是xml解析库,也支持html文档解析功能,实用功能:自动修正补全html代码. 使用流程:①导入lxml中的etree库,②利用etree.HTML(文件名)或etree.parse(本 ...

  2. UVA 211 The Domino Effect 多米诺效应 (回溯)

    骨牌无非两种放法,横着或竖着放,每次检查最r,c最小的没访问过的点即可.如果不能放就回溯. 最外面加一层认为已经访问过的位置,方便判断. #include<bits/stdc++.h> ; ...

  3. unbuntu&vim&Kali的各种小知识

    1. vmware workstation 15.0.0 2.ubuntu-18.10-desktop  使用网络地址转换 VMware workstation 1.ctrl+alt 返回  unbu ...

  4. CAD控件的鼠标事件(网页版)

    _DMxDrawXEvents::MouseEvent CAD控件中的鼠标事件. 参数 说明 LONG lType 事件类型,1鼠标移动,2是鼠标左键按下,3是鼠标右键按下,4是鼠标左键双击 5是鼠标 ...

  5. linux必会命令-查询-tail

    先说一个tail使用的例子: tail -n 20 filename 说明:显示filename最后20行. Linux下tail命令的使用方法.linux tail命令用途是依照要求将指定的文件的最 ...

  6. 【转】vxworks的default boot line说明

    boot程序的主要功能是引导vxworks 内核,所以boot程序需要知道vxworks的内核存放在何处,通过什么手段去获取.在vxworks缺省的boot程序里有一条内建的default boot ...

  7. 【贪心】bzoj1592: [Usaco2008 Feb]Making the Grade 路面修整

    贪心的经典套路:替换思想:有点抽象 Description FJ打算好好修一下农场中某条凹凸不平的土路.按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也 就是说,高度上升与高度下降的路段不能 ...

  8. 01windows常用命令及批处理

    1. 概述 复制内容:右键弹出快捷菜单,选择"标记(K)",然后选中所需要的内容,然后右键即可 粘贴内容:右键弹出快捷菜单,选择"粘贴(P)" 命令参数的路径: ...

  9. idea 启动不了

    idea 更新了新版本.  破解步骤安排完了之后 ,  发现怎么也启动不了.  没有任何提示. 于是为了查看错误信息去idea的安装目录bin下用idea.bat脚本启动发现了如下错误: 在idea6 ...

  10. DeepFaceLab小白入门(4):提取人脸图片!

    通过上面级片文章,你应该基本知道了换脸的流出,也能换出一个视频来.此时,你可能会产生好多疑问,比如每个环节点点到底是什么意思,那些黑漆漆屏幕输出的又是什么内容,我换脸效果这么差,该如何提升?等等,好奇 ...