zoukankan      html  css  js  c++  java
  • 3513: [MUTC2013]idiots

    3513: [MUTC2013]idiots

    链接

    分析:

      考虑求不合法的方案数,可以枚举一条最大的边,另外两条边要求长度和小于等于这条边。

      设dp[i]表示任选两条,长度为和为i的方案数,这是一个卷积,FFT优化。然后维护一个前缀和。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    using namespace std;
    typedef long long LL;
     
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    const int N = 270005;
    const double Pi = acos(-1.0);
    struct Com{ 
        double x, y; 
        Com() {} Com(double _x,double _y) { x = _x, y = _y; }
    }A[N];
    Com operator + (const Com &A,const Com &B) { return Com(A.x + B.x, A.y + B.y); }
    Com operator - (const Com &A,const Com &B) { return Com(A.x - B.x, A.y - B.y); }
    Com operator * (const Com &A,const Com &B) { return Com(A.x * B.x - A.y * B.y, A.x * B.y + A.y * B.x); }
     
    int rev[N], cnt[N], dp[N];
     
    void FFT(Com *a,int n,int ty) {
        for (int i = 0; i < n; ++i) if (i > rev[i]) swap(a[i], a[rev[i]]);
        Com w, w1, u, t;
        for (int m = 2; m <= n; m <<= 1) {
            w1 = Com(cos(2 * Pi / m), ty * sin(2 * Pi / m));
            for (int i = 0; i < n; i += m) {
                w = Com(1, 0);
                for (int k = 0; k < (m >> 1); ++k) {
                    u = a[i + k], t = w * a[i + k + (m >> 1)];
                    a[i + k] = u + t, a[i + k + (m >> 1)] = u - t;
                    w = w * w1;
                }
            }
        }
    }
    void solve() {
        int n = read(), Mx = 0, len = 1, lg = 0;
        for (int x, i = 1; i <= n; ++i) x = read(), cnt[x] ++, Mx = max(Mx, x);
        while (len <= Mx + Mx) len <<= 1, lg ++;
        for (int i = 0; i < len; ++i) {
            rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
            A[i] = Com(cnt[i], 0);
        }
        FFT(A, len, 1);
        for (int i = 0; i < len; ++i) A[i] = A[i] * A[i];
        FFT(A, len, -1);
        for (int i = 0; i < len; ++i) dp[i] = (A[i].x / (double)len + 0.5);
        LL ans = 0, now = 0, tot = 1ll * n * (n - 1) * (n - 2) / 6;
        for (int i = 0; i < len; ++i) {
            now += dp[i];
            if (i % 2 == 0) now -= cnt[i / 2];
            ans += 1ll * now * cnt[i];
        }
        ans /= 2;
        printf("%.7lf
    ", (1.0 - 1.0 * ans / (double)tot));
        memset(cnt, 0, sizeof(cnt));
        for (int i = 0; i < len; ++i) A[i].x = A[i].y = dp[i] = rev[i] = 0;
    }
    int main() {
        for (int T = read(); T--; solve());
        return 0;
    }
    
  • 相关阅读:
    耶鲁大学——斯金纳理论基础
    耶鲁大学——弗洛伊德(基础)
    for input 'WID' 报错
    选中当前行wid
    微信支付
    vue.js列表渲染项目实例
    批量删除
    DIV 局部刷新
    DIV块刷新
    CMD DOS命令
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10655660.html
Copyright © 2011-2022 走看看