hdu4609 3-idiots
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
int T, n, lim, c[100005], rev[270005], tmpcnt, a[100005];
const double PI=acos(-1.0);
ll d[270005];
struct Complex{
double x, y;
Complex (double xx=0.0, double yy=0.0){
x = xx;
y = yy;
}
Complex operator+(const Complex &u)const{
return Complex(x+u.x, y+u.y);
}
Complex operator-(const Complex &u)const{
return Complex(x-u.x, y-u.y);
}
Complex operator*(const Complex &u)const{
return Complex(x*u.x-y*u.y, x*u.y+y*u.x);
}
}aa[270005];
void fft(Complex a[], int opt){
for(int i=0; i<lim; i++)
if(i<rev[i])
swap(a[i], a[rev[i]]);
for(int i=2; i<=lim; i<<=1){
Complex wn=Complex(cos(PI*2/i), opt*sin(PI*2/i));
int tmp=i>>1;
for(int j=0; j<lim; j+=i){
Complex w=Complex(1.0, 0.0);
for(int k=0; k<tmp; k++){
Complex tmp1=a[j+k], tmp2=w*a[j+k+tmp];
a[j+k] = tmp1 + tmp2;
a[j+k+tmp] = tmp1 - tmp2;
w = w * wn;
}
}
}
if(opt==-1)
for(int i=0; i<lim; i++)
a[i].x /= lim;
}
int main(){
cin>>T;
while(T--){
memset(c, 0, sizeof(c));
memset(aa, 0, sizeof(aa));
lim = 1;
tmpcnt = 0;
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
c[a[i]]++;
}
sort(a+1, a+1+n);
while(lim<=a[n]+a[n]) lim <<= 1, tmpcnt++;
for(int i=0; i<lim; i++)
rev[i] = (rev[i>>1]>>1) | ((i&1)<<(tmpcnt-1));
for(int i=1; i<=a[n]; i++)
aa[i].x = c[i];
fft(aa, 1);
for(int i=0; i<lim; i++)
aa[i] = aa[i] * aa[i];
fft(aa, -1);
for(int i=0; i<=a[n]+a[n]; i++)
d[i] = (ll)(aa[i].x+0.5);
for(int i=1; i<=n; i++)
d[a[i]+a[i]]--;
for(int i=0; i<=a[n]+a[n]; i++)
d[i] /= 2;
for(int i=1; i<=a[n]+a[n]; i++)
d[i] += d[i-1];
ll ans=0;
for(int i=1; i<=n; i++){
ans += d[a[n]+a[n]] - d[a[i]];
ans -= (ll)(n-i)*(i-1);
ans -= (ll)(n-i)*(n-i-1)/2;
ans -= n - 1;
}
printf("%.7f\n", (double)ans/((ll)n*(n-1)*(n-2)/6));
}
return 0;
}
拙いものと思えども、
その手に握る其れこそが、
いつか幻想を生んでいく。