ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【BZOJ3513-MUTC2013】idiots[生成函数+容斥]

2022-07-04 15:02:45  阅读:166  来源: 互联网

标签:cop BZOJ3513 img int db 容斥 idiots res rl


题意:

给一些长度的木棍,问你构成三角形的方案数。\(n<=10^5\)

思路:

计数问题。三角形构成条件中:两短边和大于第三边即可。
可以用生成函数(fft乘法)统计出所有由两条(不同)边构成的长度和及其方案数。
然后乘上比该和小的总个数。
会发现,对于三条边(三元组),如果构成三角形会被算\(3\)次,否则被算\(2\)次。
因此不构成三元组的数量为\(\binom{n}{3}*3-前面累计的总方案\)。

code

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int N=1e6+5;
const db pi=acos(-1);
struct cop {
	db img,rl;
	friend inline cop operator*(cop u,cop v) {return (cop){u.rl*v.img+u.img*v.rl,u.rl*v.rl-u.img*v.img};}
	friend inline cop operator+(cop u,cop v) {return (cop){u.img+v.img,u.rl+v.rl};}
	friend inline cop operator-(cop u,cop v) {return (cop){u.img-v.img,u.rl-v.rl};}
}f[N];

int rev[N],up,tot[N];
void gt_up(int len) {
	up=1;int L=0;
	while(up<=len){up<<=1;L++;}
	for(int i=1;i<up;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
}

void FFT(cop *a,int op) {
	for(int i=1;i<up;i++)if(rev[i]>i)swap(a[i],a[rev[i]]);
	for(int mid=1;mid<up;mid<<=1) {
		cop w1=(cop){op*sin(pi/mid),cos(pi/mid)};
		for(int len=mid<<1,l=0;l<up;l+=len) {
			cop w=(cop){0,1};
			for(int i=0;i<mid;i++,w=w*w1) {
				int p=l+i,q=p+mid;
				cop x=a[p],y=a[q]*w;
				a[p]=x+y;a[q]=x-y;
			}
		}
	}
}
int a[N],mxa;
int main() {
	int T;scanf("%d",&T);
	while(T--) {
		mxa=0;
		int n;scanf("%d",&n);
		for(int i=0;i<n;i++) {int w;scanf("%d",&a[i]);tot[a[i]]++;mxa=max(mxa,a[i]);}
		int mxa_=mxa<<1;
		gt_up(mxa_);
		for(int i=0;i<up;i++) {f[i]=(cop){0,tot[i]};}
		FFT(f,-1);
		for(int i=0;i<up;i++) {f[i]=f[i]*f[i];}
		FFT(f,1);
		ll res=0,sm=tot[1];
		for(int i=2;i<=mxa_;i++) {
			ll cnt=(ll)(f[i].rl/up+0.5);
			if(!(i&1)) {cnt-=tot[i>>1];}
			cnt>>=1;
			res+=cnt*(sm-2);sm+=tot[i];
		}
		ll Cn_3=1ll*n*(n-1)*(n-2)/6;
		res=Cn_3*3-res;
		printf("%.7lf\n",(db)(Cn_3-res)/Cn_3);
		
		for(int i=1;i<=mxa;i++)tot[i]=0;
	}
	return 0;
}

标签:cop,BZOJ3513,img,int,db,容斥,idiots,res,rl
来源: https://www.cnblogs.com/bestime/p/16442934.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有