P3799 小 Y 拼木棒
题目背景
上道题中,小 Y 斩了一地的木棒,现在她想要将木棒拼起来。
题目描述
有 nnn 根木棒,现在从中选 444 根,想要组成一个正三角形,问有几种选法?
答案对 109+710^9+7109+7 取模。
输入格式
第一行一个整数 nnn。
第二行往下 nnn 行,每行 111 个整数,第 iii 个整数 aia_iai 代表第 iii 根木棒的长度。
输出格式
一行一个整数代表答案。
输入输出样例 #1
输入 #1
4
1
1
2
2
输出 #1
1
说明/提示
数据规模与约定
- 对于 30%30\%30% 的数据,保证 n≤5×103n \le 5 \times 10^3n≤5×103。
- 对于 100%100\%100% 的数据,保证 1≤n≤1051 \leq n \le 10^51≤n≤105,1≤ai≤5×1031 \le a_i \le 5 \times 10^31≤ai≤5×103。
关于标题:因为一些不可抗力的原因,名称进行了更改。深表歉意。
//lg3799
#include<cstdio>
using namespace std;
typedef long long ll;
const int MAXN=100010;
const int MAXL=5010;
const ll MOD=1e9+7;
int n,a[MAXN];
ll cnt[MAXL],ans;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%d",&a[i]);
if(a[i]<MAXL) cnt[a[i]]++;
}
for(int i=2;i<MAXL;++i)
{
if(cnt[i]<2) continue;
ll ci=cnt[i]*(cnt[i]-1) / 2 % MOD;
//长度为i的木棒有cnt[i]个,那么从这么多木棒中选两个出来
ll total=0;
for(int j=1;j<=i/2;++j)
{
int k=i-j;
if(k<1 || k>=MAXL) continue;
if(j==k)
{
if(cnt[j]>=2)
{
total=(total+cnt[j]*(cnt[j]-1)/2) % MOD;
}
}
else
{
total=(total+cnt[j]*cnt[k]) % MOD;
}
}
//枚举短木棒j和k(j+k=i)
ans=(ans+ci*total) % MOD;
}
printf("%lld\n",ans);
return 0;
}

905

被折叠的 条评论
为什么被折叠?



