您的位置:首页 > 大数据 > 物联网

Bzoj3513:[MUTC2013]idiots:FFT

2016-04-15 08:37 435 查看
题目链接::[MUTC2013]idiots

设s[i]长度为i的木棒出现的次数,dp[i]为两根木棍组成长度为i的方案数

那么


这是一个卷积的式子,可以用FFT来加速了

统计答案用总概率减去不合法的概率

我们一遍扫过去,扫到i时统计sum为dp[1->i]的和

因为当木根长度为i时sum中的所有方案都非法,随意非法答案总数加上sum*s[i]

注意如果i为偶数时,dp[i]中会有i/2+i/2这种方案,所以要去重

最后非法答案不要忘了/2

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=444440;
const double pi=3.141592653589793238462643383279502884197169399375105820974944;
struct cp{
double r,i;
cp(double _r=0,double _i=0):r(_r),i(_i){}
cp operator + (cp x){return cp(r+x.r,i+x.i);}
cp operator - (cp x){return cp(r-x.r,i-x.i);}
cp operator * (cp x){return cp(r*x.r-i*x.i,r*x.i+i*x.r);}
void clear(){r=i=0.0;}
}a[maxn],b[maxn],c[maxn],A[maxn];
int n,mx,N=0,L=0,rev[maxn],dig[maxn];
LL s[maxn];

void FFT(cp a[],int flag){
for (int i=0;i<N;++i) A[i]=a[rev[i]];
for (int i=0;i<N;++i) a[i]=A[i];
for (int i=2;i<=N;i<<=1){
cp wn(cos(2*pi/i),sin(2*pi/i)*flag);
for (int k=0;k<N;k+=i){
cp w(1,0);
for (int j=k;j<k+i/2;++j){
cp x=a[j],y=a[j+i/2]*w;
a[j]=x+y; a[j+i/2]=x-y;
w=w*wn;
}
}
}if (flag==-1) for (int i=0;i<N;++i) a[i].r/=N;
}

int main(){
int T; scanf("%d",&T);
while (T--){
scanf("%d",&n);
mx=0; memset(s,0,sizeof(s));
for (int i=1;i<=n;++i)
{int x;scanf("%d",&x);mx=max(x,mx);s[x]++;}
for (N=1,L=0;N<mx+1;N<<=1,L++);
N<<=1; L++; mx++;
memset(dig,0,sizeof(dig));
memset(rev,0,sizeof(rev));
for (int i=0;i<N;++i){
int len=0; a[i].clear(); b[i].clear();
for (int t=i;t;t>>=1) dig[len++]=(t&1);
for (int j=0;j<L;++j) rev[i]=(rev[i]<<1)|(dig[j]);
}
for (int i=1;i<=mx;++i)
a[i]=cp((double)s[i]),b[i]=cp((double)s[i]);
FFT(a,1); FFT(b,1);
for (int i=0;i<N;++i) c[i]=a[i]*b[i];
FFT(c,-1);
LL ans=0,tot=1LL*n*(n-1)*(n-2)/6,sum=0;
for (int i=0;i<=mx;++i){
sum+=(LL)(c[i].r+0.5);
if (i%2==0) sum-=s[i/2];
if (!s[i]) continue;
ans+=1LL*sum*s[i];
}
ans/=2;
printf("%.7lf\n",1.0-(double)ans/(double)tot);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BZOJ fft