hdu4609(FFT)

题意:选取3条边,然后选取三条边能构成三角形的概率

题解:假设我们选取是有顺序的话,选取的总方案数是n*(n-1)*(n-2)然后我们考虑到可以的方案比较难算,我们算组成不了三角形的方案数,那么就是前两条的边之和小于等于第三边的方案数,那么我们可以用FFT计算出前两条边构成长度为x的方案数m,最后我们枚举第三条长度,然后求解,因为我们求解的时候是有顺序的所以我们求出来不行的方案数需要乘以3

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mes(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define dec(i,a,b) for(int i = a; i >= b; i--)
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define lowbit(x) x&(-x)
#define pi acos(-1.0)
typedef double db;
typedef long long int ll;
typedef pair pii;
typedef complex cd;
typedef unsigned long long ull;
const ll inf = 0x3f3f3f3f;
const int mx = 3e5+5;
const int mod = 1e9+7;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
cd a[mx],b[mx];
int rev[mx];
int vis[mx];
ll ans[mx];
int bit,len;
void init(){
	for(int i = 1; i < len; i++)
		rev[i] = (rev[i>>1]>>1)|((i&1)<i) swap(p[i],p[rev[i]]);
	for(int i = 1; i < len; i <<= 1){
		cd wn = exp(cd(0,dft*pi/i));
		for(int j = 0; j < len; j += i<<1){
			cd wnk(1,0);
			for(int k = j; k < j+i; k++){
				cd x = p[k];
				cd y = wnk*p[k+i];
				p[k] = x+y;
				p[k+i] = x-y;
				wnk *= wn;
			}
		}
	}
	if(dft == -1) for(int i = 0; i < len; i++) p[i] /= len;
}
int main(){
	//freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
	int t,q,ca = 1;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		mes(vis,0);
		m = 0;
		for(int i = 1; i <= n; i++){
			int x;
			scanf("%d",&x);
			m = max(m,x);
			vis[x]++;
		}
		bit = 0;
		while((1<

 

你可能感兴趣的:(FFT)