• hdu 4609 3-idiots (FFT + 计数)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4609

    (fft) 经典套路,求 (n) 个数任意两个相加所得的数的种类/数量,只需要将数值当作指数,系数0/1表示有/没有或 (a_i) 表示该数值有 (a_i) 个,(fft) 即可,注意去重

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 3e5+7;
     
    int T, n, m, N = 100000;
    int l,r[maxn], t[maxn], c[maxn];
    ll ans[maxn], sum[maxn];
    int lim=1;
    
    const double Pi = acos(-1.0);
    struct complex{
    	double x,y;
    	complex(double xx=0,double yy=0) { x=xx,y=yy; }
    }a[maxn],b[maxn];
    complex operator + (complex a,complex b) { return complex(a.x+b.x,a.y+b.y); }
    complex operator - (complex a,complex b) { return complex(a.x-b.x,a.y-b.y); }
    complex operator * (complex a,complex b) { return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x); } 
    
    void fft(complex *A,int type){
    	for(int i=0;i<lim;i++)
    		if(i<r[i]) swap(A[i],A[r[i]]);
    	for(int mid=1;mid<lim;mid<<=1){
    		complex Wn( cos(Pi/mid),type*sin(Pi/mid));
    		for(int r=mid<<1,j=0;j<lim;j+=r){
    			complex w(1,0);
    			for(int k=0;k<mid;k++,w=w*Wn){
    				complex x=A[j+k],y=w*A[j+mid+k];
    				A[j+k]=x+y;
    				A[j+mid+k]=x-y;
    			}
    		}
    	}
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	T = read();
    	while(T--){
    		memset(a, 0, sizeof(a));
    		memset(b, 0, sizeof(b));
    		memset(t, 0, sizeof(t));
    		memset(c, 0, sizeof(c));
    		memset(ans, 0, sizeof(ans));
    		lim = 1, l = 0;
    		n=read();
    		for(int i = 1 ; i <= n ; ++i) t[i] = read(), ++c[t[i]];
    		for(int i=0;i<=N;i++) a[i].x = c[i];
    		
    		while(lim <= N + N) lim<<=1,l++;
    		for(int i=0;i<lim;i++)
    			r[i]=(r[i>>1]>>1)|(i&1)<<(l-1);
    		fft(a,1);
    		for(int i=0;i<=lim;i++) a[i]=a[i]*a[i];
    		fft(a,-1);
    		for(int i=0;i<=N + N;i++){
    			ans[i] = (ll)(a[i].x/lim+0.5);
    		}	
    		
    		for(int i = 1 ; i <= n ; ++i) --ans[t[i] + t[i]]; 
    		for(int i = 0 ; i <= N + N ; ++i) {
    			ans[i] /= 2ll;
    		}
    		
    		for(int i = 1 ; i <= N + N ; ++i){
    			sum[i] = sum[i - 1] + ans[i];
    		}
    		
    		ll val = 0;
    		for(int i = 1 ; i <= n ; ++i){
    			val += sum[N + N] - sum[t[i]];
    			val -= 1ll * (i - 1) * (n - i);
    			val -= (n - 1);
    			val -= 1ll * (n - i) * (n - i - 1) / 2;
    		}
    		ll all = 1ll * n * (n - 1) * (n - 2) / 6ll;
    		printf("%.7lf
    ", (double) val / all);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    装饰器模式
    doraemon的python 三元函数
    doraemon的python 文件操作
    doraemon的python 深浅拷贝和文件操作
    doraemon的python 集合
    doraemon的python 字典
    doraemon的python 列表
    doraemon 周总结1
    doraemon的python 练习
    doraemon的python之旅 整型、布尔值和字符串2
  • 原文地址:https://www.cnblogs.com/tuchen/p/14386636.html
Copyright © 2020-2023  润新知