zoukankan      html  css  js  c++  java
  • 解题:HDU 4609 Three Idiots

    题面

    要求组合的方法显然我们需要对桶卷积,即设$F(x)=sumlimits_{i=1}^{maxx}x^{cnt[i]}$,然后我们初步的先把$F^2(x)$卷出来,表示选两条边。然后我们发现如果用“两边之和大于第三边”来求,那么小于这两条边的可能不是最长的,所以应该枚举大于这两条边的来容斥

    注意题目中提到了不能选重复的,所以对于所有指数为偶数的项去重,还有题目要求是无序地选

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=400005,M=30,K=4e5;
     7 const double pai=acos(-1);
     8 struct cpx
     9 {
    10     double x,y;    
    11 }a[N];
    12 cpx operator + (cpx a,cpx b)
    13 {
    14     return (cpx){a.x+b.x,a.y+b.y};
    15 }
    16 cpx operator - (cpx a,cpx b)
    17 {
    18     return (cpx){a.x-b.x,a.y-b.y};
    19 }
    20 cpx operator * (cpx a,cpx b)
    21 {
    22     double x1=a.x,x2=b.x,y1=a.y,y2=b.y;
    23     return (cpx){x1*x2-y1*y2,x1*y2+x2*y1};
    24 }
    25 long long cnt[N],tot,ans;
    26 int mem[N],rev[N],lgg[N];
    27 double Sin[M],Cos[M];
    28 int n,m,T,rd;
    29 int Round(double x)
    30 {
    31     return (int)(x+0.5);
    32 }
    33 void Prework()
    34 {
    35     scanf("%d",&T);
    36     for(int i=2;i<=K;i++)
    37         lgg[i]=lgg[i>>1]+1;
    38     for(int i=1;i<=25;i++)
    39         Sin[i]=sin(2*pai/(1<<i)),Cos[i]=cos(2*pai/(1<<i));
    40 }
    41 void Trans(cpx *c,int t)
    42 {
    43     for(int i=0;i<n;i++)
    44         if(rev[i]>i) swap(c[rev[i]],c[i]);
    45     for(int i=2;i<=n;i<<=1)
    46     {
    47         int len=i>>1;
    48         cpx omg=(cpx){Cos[lgg[i]],Sin[lgg[i]]*t};
    49         for(int j=0;j<n;j+=i)
    50         {
    51             cpx ori=(cpx){1,0},tmp;
    52             for(int k=j;k<j+len;k++,ori=ori*omg)
    53                 tmp=ori*c[k+len],c[k+len]=c[k]-tmp,c[k]=c[k]+tmp;
    54         }
    55     }
    56     if(t==-1) for(int i=0;i<n;i++) c[i].x/=n;
    57 }
    58 int main()
    59 {
    60     Prework();
    61     while(T--)
    62     {
    63         scanf("%d",&n);
    64         memset(mem,0,sizeof mem),m=0;
    65         for(int i=1;i<=n;i++)
    66         {
    67             scanf("%d",&rd);
    68             mem[rd]++,m=max(m,rd);
    69         }
    70         ans=tot=1ll*n*(n-1)*(n-2)/6,n=1; while(n<=m*2) n<<=1;
    71         for(int i=0;i<n;i++) a[i].x=mem[i],a[i].y=0;
    72         for(int i=0;i<n;i++) rev[i]=(rev[i>>1]>>1)+(i&1)*(n>>1);
    73         Trans(a,1);
    74         for(int i=0;i<n;i++) a[i]=a[i]*a[i];
    75         Trans(a,-1);
    76         for(int i=1;i<=m;i++) cnt[i]=Round(a[i].x);
    77         for(int i=1;i<=m;i++)
    78         {
    79             if(i%2==0) cnt[i]-=mem[i>>1];
    80             cnt[i]>>=1,cnt[i]+=cnt[i-1];
    81         }
    82         for(int i=1;i<=m;i++) ans-=cnt[i]*mem[i];
    83         printf("%.7f
    ",(double)ans/tot);
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    goroutine
    golang package log
    golang单元测试
    golang 文件操作
    go递归打印指定目录下的所有文件及文件夹
    go语言切片作为函数参数的研究
    go数据类型之基本类型
    结束了
    codeforces358D Dima and Hares【dp】
    codeforces1081G Mergesort Strikes Back【期望dp+脑洞】
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10200331.html
Copyright © 2011-2022 走看看