zoukankan      html  css  js  c++  java
  • HDU 4609 3-idiots(FFT)

    题意:给你n个木棍,让你求取三根木棍能组成三角形的概率,其实就是问你组成三角形的方法有多少种

    思路:一点思路都没有,看了kuangbin聚聚的博客才理解了为什么要用FFT,以及之后的去重,写的很详细,但是这个题卡了内存,理解了以后用胡小兔爷的FFT,一直爆内存,主要是因为在求FFT的时候打复平面点,和他的倒数的那个位置,胡小兔爷是直接预处理打表的,QAQ,只好改成用的时候在进行计算的办法了

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 400040;
    const double PI=acos(-1.0);
    struct cp
    {
        double r,i;
        cp(){}
        cp(double _r,double _i)
        {
            r=_r;i=_i;
        }
        cp operator +(const cp &a)const
        {
            return cp(a.r+r,a.i+i);
        }
        cp operator -(const cp &a)const
        {
            return cp(r-a.r,i-a.i);
        }
        cp operator *(const cp &a)const
        {
            return cp(r*a.r-i*a.i,r*a.i+i*a.r);
        }
        cp conj()
        {
            return cp(r,-i);
        }
    };
    
    
    void change(cp y[],int len)
    {
        int i,j,k;
        for(i = 1, j = len/2;i < len-1;i++)
        {
            if(i < j)swap(y[i],y[j]);
            k = len/2;
            while( j >= k)
            {
                j -= k;
                k /= 2;
            }
            if(j < k)j += k;
        }
    }
    void fft(cp y[],int len,int on)
    {
        change(y,len);
    //    for(int i=2;i<=len;i++){
    //        printf("%d == %f
    ",i,y[i].r);
    //    }
    //    puts("");
        for(int h = 2;h <= len;h <<= 1)
        {
            cp wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
            for(int j = 0;j < len;j += h)
            {
                cp w(1,0);
                for(int k = j;k < j+h/2;k++)
                {
                    cp u = y[k];
                    cp t = w*y[k+h/2];
                    y[k] = u+t;
                    y[k+h/2] = u-t;
                    w = w*wn;
                }
            }
        }
        if(on == -1)
            for(int i = 0;i < len;i++)
                y[i].r /= len;
    }
    
    int a[N/4];
    long long num[N],sum[N];
    cp x[N];
    int main()
    {
        int T,n,m;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            memset(num,0,sizeof(num));
            for(int i=0;i<n;i++){
                scanf("%d",&a[i]);
                num[a[i]]++;
            }
            sort(a,a+n);
            m=a[n-1]+1;
            int as=1;
            while(as<2*m)as<<=1;
            for(int i=0;i<m;i++){
                x[i]=cp(num[i],0);
            }
            for(int i=m;i<as;i++){
                x[i]=cp(0,0);
            }
    //        FFT_init();
            fft(x,as,1);
            for(int i=0;i<as;i++){
                x[i]=x[i]*x[i];
            }
            fft(x,as,-1);
            for(int i=0;i<as;i++){
                num[i]=(long long)(x[i].r+0.5);
            }
            as=2*a[n-1];
            for(int i=0;i<n;i++){
                num[a[i]+a[i]]--;
            }
            for(int i=1;i<=as;i++){
                num[i]/=2;
            }
            sum[0]=0;
            for(int i=1;i<=as;i++){
                sum[i]=sum[i-1]+num[i];
            }
            long long ans=0;
            for(int i=0;i<n;i++){
                ans+=sum[as]-sum[a[i]];
                ans-=(long long)(n-1-i)*i;
                ans-=(n-1);
                ans-=(long long)(n-1-i)*(n-i-2)/2;
            }
            long long tot=(long long)n*(n-1)*(n-2)/6;
            printf("%.7f
    ",(double)ans/tot);
        }
    }
    
    
    /*
    2
    4
    1 3 3 4
    4
    2 3 3 4
    
    */
  • 相关阅读:
    jQuery 追加元素、拼接元素的方法总结(append、html、insertBefore、before等)
    Angular4.0 项目报错:Unexpected value xxxComponent' declared by the module 'xxxxModule'. Please add a @Pipe...
    数据库表约束的创建与使用之主键约束
    从零开始学虚拟DOM
    Typescript项目注意点和基本类型介绍
    JS操作符
    sass @function,@for,@mixin 的应用
    关于web优化(一)
    typescritp 导出默认接口
    The stacking context
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/9416266.html
Copyright © 2011-2022 走看看