zoukankan      html  css  js  c++  java
  • BZOJ 3513 idiots

    题目传送门

    分析:

    FFT一手统计两根棍子相加的方案

    然后一个值2S可能会被同一根S自己乘自己得到

    然后要减去

    其次,A+B和B+A会被算成两种方案,所以还要除以2

    然后不太好算合法的方案数,但是非法的很好算

    直接减去小于S的所有方案数乘以长度为S的棍子数就好了。。

    疯狂卡常2333

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
     
    #define maxn 500005
     
    using namespace std;
     
    inline int getint()
    {
        int num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
     
    struct cp{
        double a,b;
        cp(){}
        cp(double x,double y){a=x,b=y;}
        friend cp operator +(cp x,cp y)
        {return cp(x.a+y.a,x.b+y.b);}
        friend cp operator -(cp x,cp y)
        {return cp(x.a-y.a,x.b-y.b);}
        friend cp operator *(cp x,cp y)
        {return cp(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);}
    };
     
    const double pi=acos(-1.0);
    int k=1,bit;
    cp a[maxn],b[maxn];
    int rev[maxn];
    long long num1[maxn],num2[maxn];
     
    inline void fft(cp *a,int inv)
    {
        for(int i=0;i<k;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
        for(int mid=1;mid<k;mid<<=1)
        {
            cp tmp(cos(pi/mid),inv*sin(pi/mid));
            for(int i=0;i<k;i+=mid*2)
            {
                cp ret(1,0);
                for(int j=0;j<mid;j++,ret=ret*tmp)
                {
                    cp x=a[i+j],y=ret*a[i+j+mid];
                    a[i+j]=x+y,a[i+j+mid]=x-y;
                }
            }
        }
    }
     
    int main()
    {
        int T=getint();
        while(T--)
        {
            memset(a,0,sizeof a);
            int mx=0;
            long long n=getint();k=1,bit=0;
            for(int i=0;i<n;i++)
            {
                int x=getint();mx=max(mx,x);
                a[x].a++;
            }
            while(k<(mx+1)*2-1)k<<=1;
            while((1<<bit)<k)bit++;
            for(int i=0;i<k;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
            for(int i=0;i<k;i++)b[i]=a[i];
            fft(a,1);
            for(int i=0;i<k;i++)a[i]=a[i]*a[i];
            fft(a,-1);
            for(int i=0;i<k;i++)
            {
                num1[i]=(long long)(b[i].a+0.5),
                num2[i]=(long long)(a[i].a/k+0.5);
                if(!(i&1))num2[i]-=num1[i>>1];
                num2[i]>>=1;
            }
            long long ans=(1ll*n*(n-1)*(n-2))/6;
            for(int i=1;i<=mx;i++)num2[i]+=num2[i-1],ans-=num2[i]*num1[i];
            printf("%.7lf
    ",1.0*ans*6/(n*(n-1)*(n-2)));
        }
    }
    View Code

  • 相关阅读:
    异步CTP(Async CTP)为什么那样工作?
    Async Console Programs 异步控制台程序
    Async and Await 异步和等待
    OpenJudge计算概论-自整除数
    OpenJudge计算概论-整数的个数
    OpenJudge计算概论-找和为K的两个元素
    OpenJudge计算概论-找出第k大的数
    OpenJudge计算概论-异常细胞检测
    OpenJudge计算概论-数组逆序重放
    OpenJudge计算概论-数字求和
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12064468.html
Copyright © 2011-2022 走看看