BJTUOJ 1854 hwf的三角形(组合数学)

Description

由正 n n 边形的顶点构成的所有三角形中,有多少种互不全等的三角形

Input

第一行为一个整数t(1t2000),表示数据的组数。接下来对于每组数据:

第一行为一个整数 n(3n109) n ( 3 ≤ n ≤ 10 9 ) ,表示正多边形的边数。

Output

对于每组数据,输出一行:

第一行为一个整数,表示互不全等三角形的个数。

Sample Input

1
3

Sample Output

1

Solution

n n 个顶点按顺时针编号,考虑三角形三个顶点的编号差,问题即转化为求满足a,b,c1, abc a ≤ b ≤ c , a+b+c=n a + b + c = n 的三元组 (a,b,c) ( a , b , c ) 的个数,进一步的即为求满足 a,b,c0 a , b , c ≥ 0 , abc a ≤ b ≤ c , a+b+c=n3 a + b + c = n − 3 的三元组 (a,b,c) ( a , b , c ) 个数,令 n=n3 n = n − 3 ,答案分成四部分,即 a<b<c a < b < c a=b<c a = b < c a<b=c a < b = c a=b=c a = b = c

对于 a=b=c a = b = c 的情况,需要 3|n 3 | n 才有一种方案 ,方案数记为 ans1 a n s 1

对于 a=b<c a = b < c 的情况,显然 a,b a , b 取值区间为 [0,n3] [ 0 , ⌊ n 3 ⌋ ] ,方案数为 ans2=n3+1 a n s 2 = ⌊ n 3 ⌋ + 1 ,注意当 3|n 3 | n 时需要减 1 1 表示去掉a=b=c的情况

对于 a<b=c a < b = c 的情况,假设方案数为 ans3 a n s 3 ,如果 n n 为奇数,那么a的取值集合为 [0,n3] [ 0 , ⌊ n 3 ⌋ ] 中的奇数,共 n3+12 ⌊ ⌊ n 3 ⌋ + 1 2 ⌋ 个,如果 n n 为偶数,那么a的取值集合为 [0,n3] [ 0 , ⌊ n 3 ⌋ ] 中的偶数,共 n3+1n3+12 ⌊ n 3 ⌋ + 1 − ⌊ ⌊ n 3 ⌋ + 1 2 ⌋ 个,同样的注意 3|n 3 | n 时需要减 1 1 表示去掉a=b=c的情况

对于 a<b<c a < b < c 的情况,假设方案数为 ans4 a n s 4 ,由于满足 a,b,c0,a+b+c=n a , b , c ≥ 0 , a + b + c = n 的方案数组成即为 ans1+3(ans2+ans3)+6ans4 a n s 1 + 3 ⋅ ( a n s 2 + a n s 3 ) + 6 ⋅ a n s 4 ,而该方案数即为把 n n 个物品放到3个盒子中且盒子可以为空的方案数,即由插板法知答案为 C2n+2 C n + 2 2 ,以此求出 ans4 a n s 4

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=100001;
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        n-=3;
        ll sum=(ll)(n+1)*(n+2)/2;
        int ans1=n%3==0?1:0;//a=b=c
        int ans2=n/3+1-ans1;//a=b<c
        int ans3;
        if(n&1)ans3=(n/3+1)/2-ans1;
        else ans3=n/3+1-(n/3+1)/2-ans1;
        sum-=(ans1+3ll*ans2+3ll*ans3);
        sum/=6;//a<b<c 
        sum=sum+ans1+ans2+ans3;
        printf("%lld\n",sum);
    } 
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值