链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2396
题解
诗曰:推式子一小时,写代码一分钟
三条边只要满足两条小边加起来大于大边,就能构成三角形
所以这题就是求:满足
a<b<c
a
<
b
<
c
,且
a+b>c
a
+
b
>
c
的
(a,b,c)
(
a
,
b
,
c
)
个数
我枚举
c
c
,现在要找的数对个数,直接算的话,可能答案中还要包含
n
n
,干脆反过来算,求的
(a,b)
(
a
,
b
)
个数
我枚举
a=[1,c−1]
a
=
[
1
,
c
−
1
]
,对应
b
b
的上界就是,再减去
a=b
a
=
b
的情况,除以
2
2
,即得到且
a+b≤c
a
+
b
≤
c
的数对
(a,b)
(
a
,
b
)
的数量
那么对于枚举的
c
c
,数对的个数就是
(∑c−1a=1c−a)−⌊c2⌋=c(c−1)2−⌊c2⌋
(
∑
a
=
1
c
−
1
c
−
a
)
−
⌊
c
2
⌋
=
c
(
c
−
1
)
2
−
⌊
c
2
⌋
答案等于
C3n−(∑nc=3c(c−1)2−⌊c2⌋)
C
n
3
−
(
∑
c
=
3
n
c
(
c
−
1
)
2
−
⌊
c
2
⌋
)
化简一下(也就一整张
A4
A
4
纸),得到一个
O(1)
O
(
1
)
的式子(就是我程序里写的那一段)
代码
//容斥
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ll N, ans;
while(scanf("%lld",&N),N>=3)
{
if(N&1)ans=(N-1)*(N+1)/4;
else ans=(N-2)*(N)/4+N/2;
ans-=N*(N+1)*(N-1)/6;
ans=N*(N-1)*(N-2)/6+ans/2;
printf("%lld\n",ans);
}
return 0;
}