1. 程式人生 > >luogu3799 妖夢拼木棒

luogu3799 妖夢拼木棒

light cst TE OS max 三角形 algo 組成 AI

題目大意

有n根木棒,現在從中選4根,想要組成一個正三角形,問有幾種選法?木棒長度都<=5000。

題解

根據容斥原理,三角形兩條邊分別由長度相等的單根木棒組成,另一條邊由兩條小於該邊長的木棒構成。由此想到了乘法原理。我們設置一數組$a$記錄長度為$i$的木棒有多少個,則對於一個邊長$e$,選兩條單邊有$C_{a_e}^2=\frac{a_e(a_e -1)}{2}$種選法,另外兩條構成一條邊的木棍有$\sum_{i+j=e}a_i a_j$。像這樣枚舉即可。

#include <cstdio>
#include <cstdarg>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

#define ll long long
#define ModMult(x, y) (x * y % P)
#define ModPlus(x, y) ((x + y) % P)
#define Comb2(x) (x * (x - 1) / 2 % P)

const int MAX_VAL_RANGE = 5010;
const ll P = 1e9 + 7;
ll ValCnt[MAX_VAL_RANGE];

int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		int x;
		scanf("%d", &x);
		ValCnt[x]++;
	}
	ll ans = 0;
	for (int i = 1; i <= 2500; i++)
	{
		ans = ModPlus(ans, ModMult(Comb2(ValCnt[i]), Comb2(ValCnt[i * 2])));
		for (int j = i + 1; j <= 5000 - i; j++)
			ans = ModPlus(ans, ModMult(ModMult(ValCnt[i], ValCnt[j]), Comb2(ValCnt[i + j])));
	}
	printf("%lld\n", ans);
	return 0;
}

  

luogu3799 妖夢拼木棒