[Luogu3799] 妖梦拼木棒

题目背景

上道题中,妖梦斩了一地的木棒,现在她想要将木棒拼起来。

题目描述

有n根木棒,现在从中选4根,想要组成一个正三角形,问有几种选法?

输入输出格式

输入格式:

第一行一个整数n

第二行n个整数,a1,a2,……an(0<ai<=5000),代表每根木棒的长度。

输出格式:

一行一个整数,对1e9+7取模

输入输出样例

输入样例#1: 复制
4 1 1 2 2
输出样例#1: 复制
1

说明

对于30%的数据 N<=5000

对于100%的数据 N<=100000

by-szc

 


 

 

简单的组合数学。

 


 

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace std;
#define reg register 
inline int read() {
    int res = 0;char ch=getchar();bool fu=0;
    while(!isdigit(ch)) {if(ch=='-')fu=1;ch=getchar();}
    while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
    return fu?-res:res;
}
#define mod 1000000007
int C[5005][5005];
int n;
int tot[5005];
int ans;

int main()
{
    n = read();
    C[0][0] = 1;
    for (reg int i = 1 ; i <= 5000 ; i ++)
    {
        C[i][0] = 1;
        for (reg int j = 1 ; j <= i ; j ++)
            C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
    }
    for (reg int i = 1 ; i <= n ; i ++) tot[read()]++;
    for (reg int i = 2 ; i <= 5000 ; i ++)
        if (tot[i] >= 2) 
            for (reg int j = 1 ; j <= i / 2 ; j ++)
            {
                if (tot[j] and tot[i-j] and j != i - j) ans = (ans + C[tot[i]][2] * tot[j] % mod * tot[i-j] % mod) % mod;
                if (tot[j] and tot[i-j] >= 2 and j == i - j) ans = (ans + C[tot[i]][2] * C[tot[j]][2] % mod) % mod;
            }
                
    cout << ans << endl;
    return 0;
}

 

posted @ 2018-09-10 19:06  zZhBr  阅读(175)  评论(0编辑  收藏  举报